Single cell seq after sorting for PhenoID

sample1 = Neurons1 sample2 = Neurons2 sample3 = Glia1 - Astrocytes (CD44+) sample4 = Glia2 - Radial Glia (CD44-)

In HPC I have run steps of scrnabox (custom pipeline in progress) 1. Cell Ranger for feature seq 2. Create Seurat Objects 3. Apply minimum filtering and calculate percent mitochondria.

I have technical 3 replicates with hashtag labels at this point I haven’t yet demultiplex the hashtags. The data here will be treated as one sample. I sorted three separate samples and pooled them together.

# set up the environment

library(Seurat)
library(dplyr)
library(Matrix)
library(ggplot2)

rm(list = ls())

Read in the seurat objects made in compute canada


# this seems to never load I'll use step 3 output that has some filtering 
# nFeature_RNA > 180 and percent.mt < 25

pathway <- "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/"

Neurons1 <- readRDS(paste(pathway,"seu1.rds",sep = ""))
Neurons2 <- readRDS(paste(pathway,"seu2.rds",sep = ""))
Glia1 <- readRDS(paste(pathway,"seu3.rds",sep = ""))
Glia2 <- readRDS(paste(pathway,"seu4.rds",sep = ""))

Neurons1
An object of class Seurat 
33541 features across 3952 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
Neurons2
An object of class Seurat 
33541 features across 34830 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
Glia1
An object of class Seurat 
33541 features across 54723 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
Glia2
An object of class Seurat 
33541 features across 10338 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO

Have a look at the objects that already have some filtering

See the violin plots


VlnPlot(Neurons1, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)


VlnPlot(Neurons1, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 500)
Warning: Removed 873 rows containing non-finite values (stat_ydensity).
Warning: Removed 873 rows containing missing values (geom_point).

VlnPlot(Neurons1, pt.size = 0.10, features = c("nCount_RNA"), y.max = 2000)
Warning: Removed 546 rows containing non-finite values (stat_ydensity).
Warning: Removed 546 rows containing missing values (geom_point).

# filter more cells

Neuron1.ft <- subset(Neurons1, subset = nFeature_RNA > 250 & nCount_RNA > 250 & nCount_RNA < 10000) 
Neuron1.ft
An object of class Seurat 
33541 features across 1833 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
# 33541 features across 1833 samples

Neurons 2 - CD56++


VlnPlot(Neurons2, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)

VlnPlot(Neurons2, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 500)
Warning: Removed 5653 rows containing non-finite values (stat_ydensity).
Warning: Removed 5653 rows containing missing values (geom_point).

VlnPlot(Neurons2, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 1000)
Warning: Removed 2379 rows containing non-finite values (stat_ydensity).
Warning: Removed 2379 rows containing missing values (geom_point).

VlnPlot(Neurons2, pt.size = 0.10, features = c("nCount_RNA"), y.max = 2000)
Warning: Removed 2264 rows containing non-finite values (stat_ydensity).
Warning: Removed 2264 rows containing missing values (geom_point).

# filter more cells

Neuron2.ft <- subset(Neurons2, subset = nFeature_RNA > 500 & nCount_RNA > 500 & nCount_RNA < 10000) 
Neuron2.ft
An object of class Seurat 
33541 features across 5190 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO

Glia1 - Astrocyte data


VlnPlot(Glia1, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)


VlnPlot(Glia1, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 5000)
Warning: Removed 82 rows containing non-finite values (stat_ydensity).
Warning: Removed 82 rows containing missing values (geom_point).

VlnPlot(Glia1, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 1000)
Warning: Removed 11811 rows containing non-finite values (stat_ydensity).
Warning: Removed 11811 rows containing missing values (geom_point).

VlnPlot(Glia1, pt.size = 0.10, features = c("nCount_RNA"), y.max = 1000)
Warning: Removed 25751 rows containing non-finite values (stat_ydensity).
Warning: Removed 25751 rows containing missing values (geom_point).

VlnPlot(Glia1, pt.size = 0.10, features = c("nCount_RNA"), y.max = 12000)
Warning: Removed 252 rows containing non-finite values (stat_ydensity).
Warning: Removed 252 rows containing missing values (geom_point).

# extreme filter

Glia1.ft <- subset(Glia1, subset = nFeature_RNA > 500 & nCount_RNA > 300 & nCount_RNA < 10000) 
Glia1.ft
An object of class Seurat 
33541 features across 37813 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
Glia1
An object of class Seurat 
33541 features across 54723 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
VlnPlot(Glia1.ft, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)

NA
NA
NA
NA
NA

Glia2 - Radial Glia


## Filter Glia 2
VlnPlot(Glia2, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)


VlnPlot(Glia2, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 5000)
Warning: Removed 61 rows containing non-finite values (stat_ydensity).
Warning: Removed 61 rows containing missing values (geom_point).

VlnPlot(Glia2, pt.size = 0.10, features = c("nFeature_RNA"), y.max = 1000)
Warning: Removed 2435 rows containing non-finite values (stat_ydensity).
Warning: Removed 2435 rows containing missing values (geom_point).

VlnPlot(Glia2, pt.size = 0.10, features = c("nCount_RNA"), y.max = 1000)
Warning: Removed 3194 rows containing non-finite values (stat_ydensity).
Warning: Removed 3194 rows containing missing values (geom_point).

VlnPlot(Glia2, pt.size = 0.10, features = c("nCount_RNA"), y.max = 12000)
Warning: Removed 199 rows containing non-finite values (stat_ydensity).
Warning: Removed 199 rows containing missing values (geom_point).

# extreme filter

Glia2.ft <- subset(Glia1, subset = nFeature_RNA > 500 & nCount_RNA > 500 & nCount_RNA < 10000) 
Glia2.ft
An object of class Seurat 
33541 features across 37813 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO
VlnPlot(Glia1.ft, pt.size = 0.10, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)


# there are so many suposed cells I am concerned the high read cells are actually doublets. 

Analyze each dataset - get clusters


# cluster the neurons
seu <- Neuron1.ft
seu$orig.ident <- 'Neurons1'

seu <- NormalizeData(seu, normalization.method = "LogNormalize", scale.factor = 10000)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- FindVariableFeatures(seu, selection.method = "vst", nfeatures = 2000)
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
# Identify the 10 most highly variable genes
top10 <- head(VariableFeatures(seu), 10)
# plot variable features with and without labels
plot1 <- VariableFeaturePlot(seu)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
When using repel, set xnudge and ynudge to 0 for optimal results
seu <- ScaleData(seu)
Centering and scaling data matrix

  |                                                                                                      
  |                                                                                                |   0%
  |                                                                                                      
  |================================================                                                |  50%
  |                                                                                                      
  |================================================================================================| 100%
seu <- RunPCA(seu)
PC_ 1 
Positive:  CDH19, MPZ, COL4A1, COL4A2, COL3A1, ZEB2, CTSC, OLFML2A, MIA, FN1 
       NRXN1, ERBB3, TGFBR2, COL14A1, COL1A2, FST, COL5A2, COL28A1, PLAT, SHC4 
       NTM, PMEPA1, KCTD12, CAVIN3, SOX10, LAMC1, BGN, IFI16, LIMCH1, GAS2L3 
Negative:  CLU, PTGDS, DLK1, SPARCL1, PTN, APOE, SAT1, TFPI2, GDF10, HPD 
       TMSB4X, C1orf61, MGST1, TRH, NRIP3, RBP4, WIF1, NUPR1, IGFBP7, LIX1 
       FGFBP1, ESM1, TPPP3, GNG11, BAALC-AS2, BAALC, LY6H, WNT2B, SFRP2, CRYAB 
PC_ 2 
Positive:  CELF4, ANK3, CACNA2D1, PCDH9, NCKAP5, CHGB, SYT1, NEUROD1, PCLO, GNB3 
       OTX2, STMN2, PTPRR, INA, OCIAD2, IMPG2, DCX, DYNC1I1, SSTR2, ZFHX4 
       BTBD8, STMN1, GRIA2, MARCH1, SLC1A2, ATP1A3, STMN4, AMER2, BEX1, FAM19A4 
Negative:  CDH19, COL3A1, MPZ, CTSC, OLFML2A, COL4A2, COL4A1, MIA, VIM, FN1 
       TGFBR2, COL1A2, ERBB3, ZEB2, S100B, SPARC, COL14A1, S100A10, IFITM3, COL5A2 
       CAVIN3, PLAT, COL28A1, SOX10, FST, PLEKHA4, GAS2L3, CXCL12, ITIH5, LGALS1 
PC_ 3 
Positive:  PCAT4, IMPG2, NEUROD1, NRXN1, CDH19, PLPPR4, TPH1, SYT1, ZEB2, MPZ 
       MIA, GSG1, STMN2, OLFML2A, SST, OLFM3, FAM19A4, CTSC, GNB3, PTPRR 
       BTBD8, COL3A1, GAS2L3, BCAT1, SOX10, COL4A2, ERBB3, CHGB, SORCS1, COL28A1 
Negative:  TPBG, SLC7A8, WLS, FSTL1, HES1, ANO10, PAPPA2, CDH2, MSX1, SLC2A1 
       ZFP36L1, PIP5K1B, NFIA, TSC22D1, SLCO1C1, SOX2, PRNP, LINC00473, SPRY1, WIF1 
       NOV, COLEC12, PLCG2, GDF10, SPATS2L, RRBP1, BMP7, PAG1, WFIKKN2, RFX4 
PC_ 4 
Positive:  EOMES, MGAT4C, ELAVL3, LHX1, RASGRP1, ADCYAP1, ELAVL4, SLC16A12, CELF4, TSHZ2 
       PTPRO, KCNK1, SCN9A, RELN, EPS8, RAB3B, SLIT1, GRID2, ASCL1, KRT222 
       ZNF385D, DCLK1, BDNF, ELAVL2, RGMB, PLCXD3, UNC5D, RALYL, PPP1R14C, DNER 
Negative:  PCAT4, TPH1, IMPG2, BCAT1, SST, FAM19A4, BTBD8, ETV3L, GSG1, PLPPR4 
       IL15, GABRG2, PDE6H, OLFM3, GNB3, CLSTN2, CRABP2, RBFOX1, AC007349.2, LINC02208 
       AIPL1, RD3, KCNH5, NCKAP5, PRKG2, AANAT, LRRC39, ANO2, ISOC1, AP000459.1 
PC_ 5 
Positive:  PTN, PTPRZ1, SPARCL1, MEGF10, ESM1, DLK1, GABBR2, ATP1A2, NRIP3, GDF10 
       NELL2, SOX2, CBLN1, APCDD1, SYTL4, SERPINI1, ARHGAP26, PTGDS, VIPR2, FTL 
       MARCKS, GNG11, TRH, IL17RD, EPHB1, RBP4, RSPO2, APOE, OGFRL1, AKR1C1 
Negative:  CYP1B1, CP, ECEL1, CXCL14, IGFBP3, WIF1, WFIKKN2, MALAT1, FHIT, EPAS1 
       SLC4A10, EMX2, PAPPA2, TRPM3, EFEMP1, BMP4, MGP, KCNJ13, ID1, EXPH5 
       KRT18, KRT8, FBLN1, MSX1, FOS, GPNMB, DCN, CDC42EP3, COL6A3, SERPINF1 
Idents(seu) <- 'orig.ident'
plot <- DimPlot(seu, reduction = "pca")


plot3 <- ElbowPlot(seu,ndims = 50)
plot3


plot2
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Removed 13701 rows containing missing values (geom_point).

plot

NA
NA
NA

# umap

seu <- RunUMAP(seu, reduction = "pca", n.neighbors = 43, dims = 1:25)
Warning: The default method for RunUMAP has changed from calling Python UMAP via reticulate to the R-native UWOT using the cosine metric
To use Python UMAP via reticulate, set umap.method to 'umap-learn' and metric to 'correlation'
This message will be shown once per session
08:59:48 UMAP embedding parameters a = 0.9922 b = 1.112
08:59:48 Read 1833 rows and found 25 numeric columns
08:59:48 Using Annoy for neighbor search, n_neighbors = 43
08:59:48 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
08:59:48 Writing NN index file to temp file /var/folders/k4/khtkczkd5tn732ftjpwgtr240000gn/T//RtmpioYRC5/file1726b7ea878e1
08:59:48 Searching Annoy index using 1 thread, search_k = 4300
08:59:48 Annoy recall = 100%
08:59:49 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 43
08:59:49 Initializing from normalized Laplacian + noise (using irlba)
08:59:49 Commencing optimization for 500 epochs, with 107418 positive edges
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
08:59:53 Optimization finished
DimPlot(seu, reduction = "umap", group.by = "orig.ident")

NA
NA
NA

Make the clusters Neurons1


seu <- FindNeighbors(seu, dims = 1:25, k.param = 43)
Computing nearest neighbor graph
Computing SNN
seu <- FindClusters(seu, resolution = c(0,0.2,0.25,0.5,0.8))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 1.0000
Number of communities: 1
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8606
Number of communities: 4
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8446
Number of communities: 5
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7787
Number of communities: 6
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7092
Number of communities: 8
Elapsed time: 0 seconds
seu <- FindClusters(seu, resolution = c(1.2))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1833
Number of edges: 146997

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.6403
Number of communities: 10
Elapsed time: 0 seconds
library(clustree)
Loading required package: ggraph

Attaching package: ‘ggraph’

The following object is masked from ‘package:sp’:

    geometry
clustree(seu, prefix = "RNA_snn_res.")

DimPlot(seu)

# look a lot at the clusers

VlnPlot(seu, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), group.by = 'seurat_clusters', ncol = 1)

# these cells might be grouping by - how much MT and number of Features
# clusters 4,5,6 have more features

VlnPlot(seu, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), group.by = 'RNA_snn_res.0.25', ncol = 1)

# here cluster 3 has higher expression, cluster 1 and 4 have similar Features RNA
# cluster 0 has higher percent MT levels

VlnPlot(seu, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), group.by = 'RNA_snn_res.0.5', ncol = 1)

VlnPlot(seu, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), group.by = 'RNA_snn_res.0.2', ncol = 1)

# now only cluster 0 have high MT and low features, clusters 1,2,3 have simiular RNA and Counts

Find the cluster markers for Neurons1

Idents(seu) <- 'RNA_snn_res.0.2'
ClusterMarkers <- FindAllMarkers(seu)
Calculating cluster 0

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~10s          
  |++                                                | 2 % ~09s          
  |++                                                | 3 % ~09s          
  |+++                                               | 4 % ~09s          
  |+++                                               | 5 % ~09s          
  |++++                                              | 6 % ~09s          
  |++++                                              | 7 % ~09s          
  |+++++                                             | 8 % ~08s          
  |+++++                                             | 9 % ~08s          
  |++++++                                            | 10% ~09s          
  |++++++                                            | 11% ~08s          
  |+++++++                                           | 12% ~08s          
  |+++++++                                           | 13% ~08s          
  |++++++++                                          | 14% ~08s          
  |++++++++                                          | 15% ~08s          
  |+++++++++                                         | 16% ~08s          
  |+++++++++                                         | 17% ~08s          
  |++++++++++                                        | 18% ~08s          
  |++++++++++                                        | 19% ~07s          
  |+++++++++++                                       | 20% ~07s          
  |+++++++++++                                       | 21% ~07s          
  |++++++++++++                                      | 22% ~07s          
  |++++++++++++                                      | 23% ~07s          
  |+++++++++++++                                     | 24% ~07s          
  |+++++++++++++                                     | 26% ~07s          
  |++++++++++++++                                    | 27% ~07s          
  |++++++++++++++                                    | 28% ~07s          
  |+++++++++++++++                                   | 29% ~07s          
  |+++++++++++++++                                   | 30% ~06s          
  |++++++++++++++++                                  | 31% ~06s          
  |++++++++++++++++                                  | 32% ~06s          
  |+++++++++++++++++                                 | 33% ~06s          
  |+++++++++++++++++                                 | 34% ~06s          
  |++++++++++++++++++                                | 35% ~06s          
  |++++++++++++++++++                                | 36% ~06s          
  |+++++++++++++++++++                               | 37% ~06s          
  |+++++++++++++++++++                               | 38% ~06s          
  |++++++++++++++++++++                              | 39% ~06s          
  |++++++++++++++++++++                              | 40% ~05s          
  |+++++++++++++++++++++                             | 41% ~05s          
  |+++++++++++++++++++++                             | 42% ~05s          
  |++++++++++++++++++++++                            | 43% ~05s          
  |++++++++++++++++++++++                            | 44% ~05s          
  |+++++++++++++++++++++++                           | 45% ~05s          
  |+++++++++++++++++++++++                           | 46% ~05s          
  |++++++++++++++++++++++++                          | 47% ~05s          
  |++++++++++++++++++++++++                          | 48% ~05s          
  |+++++++++++++++++++++++++                         | 49% ~05s          
  |+++++++++++++++++++++++++                         | 50% ~05s          
  |++++++++++++++++++++++++++                        | 51% ~04s          
  |+++++++++++++++++++++++++++                       | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |++++++++++++++++++++++++++++                      | 54% ~04s          
  |++++++++++++++++++++++++++++                      | 55% ~04s          
  |+++++++++++++++++++++++++++++                     | 56% ~04s          
  |+++++++++++++++++++++++++++++                     | 57% ~04s          
  |++++++++++++++++++++++++++++++                    | 58% ~04s          
  |++++++++++++++++++++++++++++++                    | 59% ~04s          
  |+++++++++++++++++++++++++++++++                   | 60% ~04s          
  |+++++++++++++++++++++++++++++++                   | 61% ~04s          
  |++++++++++++++++++++++++++++++++                  | 62% ~03s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
  |++++++++++++++++++++++++++++++++++                | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=09s  
Calculating cluster 1

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~08s          
  |++                                                | 2 % ~08s          
  |++                                                | 3 % ~08s          
  |+++                                               | 4 % ~08s          
  |+++                                               | 5 % ~07s          
  |++++                                              | 6 % ~07s          
  |++++                                              | 7 % ~07s          
  |+++++                                             | 8 % ~07s          
  |+++++                                             | 9 % ~07s          
  |++++++                                            | 10% ~07s          
  |++++++                                            | 11% ~07s          
  |+++++++                                           | 12% ~07s          
  |+++++++                                           | 13% ~07s          
  |++++++++                                          | 14% ~07s          
  |++++++++                                          | 15% ~07s          
  |+++++++++                                         | 16% ~06s          
  |+++++++++                                         | 18% ~06s          
  |++++++++++                                        | 19% ~06s          
  |++++++++++                                        | 20% ~06s          
  |+++++++++++                                       | 21% ~06s          
  |+++++++++++                                       | 22% ~06s          
  |++++++++++++                                      | 23% ~06s          
  |++++++++++++                                      | 24% ~06s          
  |+++++++++++++                                     | 25% ~06s          
  |+++++++++++++                                     | 26% ~06s          
  |++++++++++++++                                    | 27% ~06s          
  |++++++++++++++                                    | 28% ~06s          
  |+++++++++++++++                                   | 29% ~05s          
  |+++++++++++++++                                   | 30% ~05s          
  |++++++++++++++++                                  | 31% ~05s          
  |++++++++++++++++                                  | 32% ~05s          
  |+++++++++++++++++                                 | 33% ~05s          
  |++++++++++++++++++                                | 34% ~05s          
  |++++++++++++++++++                                | 35% ~05s          
  |+++++++++++++++++++                               | 36% ~05s          
  |+++++++++++++++++++                               | 37% ~05s          
  |++++++++++++++++++++                              | 38% ~05s          
  |++++++++++++++++++++                              | 39% ~05s          
  |+++++++++++++++++++++                             | 40% ~05s          
  |+++++++++++++++++++++                             | 41% ~05s          
  |++++++++++++++++++++++                            | 42% ~04s          
  |++++++++++++++++++++++                            | 43% ~04s          
  |+++++++++++++++++++++++                           | 44% ~04s          
  |+++++++++++++++++++++++                           | 45% ~04s          
  |++++++++++++++++++++++++                          | 46% ~04s          
  |++++++++++++++++++++++++                          | 47% ~04s          
  |+++++++++++++++++++++++++                         | 48% ~04s          
  |+++++++++++++++++++++++++                         | 49% ~04s          
  |++++++++++++++++++++++++++                        | 51% ~04s          
  |++++++++++++++++++++++++++                        | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |+++++++++++++++++++++++++++                       | 54% ~04s          
  |++++++++++++++++++++++++++++                      | 55% ~04s          
  |++++++++++++++++++++++++++++                      | 56% ~03s          
  |+++++++++++++++++++++++++++++                     | 57% ~03s          
  |+++++++++++++++++++++++++++++                     | 58% ~03s          
  |++++++++++++++++++++++++++++++                    | 59% ~03s          
  |++++++++++++++++++++++++++++++                    | 60% ~03s          
  |+++++++++++++++++++++++++++++++                   | 61% ~03s          
  |+++++++++++++++++++++++++++++++                   | 62% ~03s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |++++++++++++++++++++++++++++++++                  | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=08s  
Calculating cluster 2

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~06s          
  |++                                                | 2 % ~06s          
  |++                                                | 3 % ~05s          
  |+++                                               | 4 % ~05s          
  |+++                                               | 5 % ~05s          
  |++++                                              | 6 % ~05s          
  |++++                                              | 8 % ~05s          
  |+++++                                             | 9 % ~05s          
  |+++++                                             | 10% ~05s          
  |++++++                                            | 11% ~05s          
  |++++++                                            | 12% ~05s          
  |+++++++                                           | 13% ~05s          
  |+++++++                                           | 14% ~05s          
  |++++++++                                          | 15% ~05s          
  |+++++++++                                         | 16% ~05s          
  |+++++++++                                         | 17% ~04s          
  |++++++++++                                        | 18% ~04s          
  |++++++++++                                        | 19% ~04s          
  |+++++++++++                                       | 20% ~04s          
  |+++++++++++                                       | 22% ~04s          
  |++++++++++++                                      | 23% ~04s          
  |++++++++++++                                      | 24% ~04s          
  |+++++++++++++                                     | 25% ~04s          
  |+++++++++++++                                     | 26% ~04s          
  |++++++++++++++                                    | 27% ~04s          
  |++++++++++++++                                    | 28% ~04s          
  |+++++++++++++++                                   | 29% ~04s          
  |++++++++++++++++                                  | 30% ~04s          
  |++++++++++++++++                                  | 31% ~04s          
  |+++++++++++++++++                                 | 32% ~04s          
  |+++++++++++++++++                                 | 33% ~04s          
  |++++++++++++++++++                                | 34% ~04s          
  |++++++++++++++++++                                | 35% ~04s          
  |+++++++++++++++++++                               | 37% ~03s          
  |+++++++++++++++++++                               | 38% ~03s          
  |++++++++++++++++++++                              | 39% ~03s          
  |++++++++++++++++++++                              | 40% ~03s          
  |+++++++++++++++++++++                             | 41% ~03s          
  |+++++++++++++++++++++                             | 42% ~03s          
  |++++++++++++++++++++++                            | 43% ~03s          
  |+++++++++++++++++++++++                           | 44% ~03s          
  |+++++++++++++++++++++++                           | 45% ~03s          
  |++++++++++++++++++++++++                          | 46% ~03s          
  |++++++++++++++++++++++++                          | 47% ~03s          
  |+++++++++++++++++++++++++                         | 48% ~03s          
  |+++++++++++++++++++++++++                         | 49% ~03s          
  |++++++++++++++++++++++++++                        | 51% ~03s          
  |++++++++++++++++++++++++++                        | 52% ~03s          
  |+++++++++++++++++++++++++++                       | 53% ~03s          
  |+++++++++++++++++++++++++++                       | 54% ~03s          
  |++++++++++++++++++++++++++++                      | 55% ~02s          
  |++++++++++++++++++++++++++++                      | 56% ~02s          
  |+++++++++++++++++++++++++++++                     | 57% ~02s          
  |++++++++++++++++++++++++++++++                    | 58% ~02s          
  |++++++++++++++++++++++++++++++                    | 59% ~02s          
  |+++++++++++++++++++++++++++++++                   | 60% ~02s          
  |+++++++++++++++++++++++++++++++                   | 61% ~02s          
  |++++++++++++++++++++++++++++++++                  | 62% ~02s          
  |++++++++++++++++++++++++++++++++                  | 63% ~02s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~02s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~02s          
  |++++++++++++++++++++++++++++++++++                | 67% ~02s          
  |++++++++++++++++++++++++++++++++++                | 68% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~02s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~01s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~01s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~01s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=06s  
Calculating cluster 3

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~09s          
  |++                                                | 2 % ~09s          
  |++                                                | 3 % ~09s          
  |+++                                               | 4 % ~09s          
  |+++                                               | 5 % ~09s          
  |++++                                              | 6 % ~09s          
  |++++                                              | 7 % ~08s          
  |+++++                                             | 8 % ~08s          
  |+++++                                             | 9 % ~09s          
  |++++++                                            | 10% ~09s          
  |++++++                                            | 11% ~08s          
  |+++++++                                           | 12% ~08s          
  |+++++++                                           | 13% ~08s          
  |++++++++                                          | 14% ~08s          
  |++++++++                                          | 15% ~08s          
  |+++++++++                                         | 16% ~08s          
  |+++++++++                                         | 18% ~08s          
  |++++++++++                                        | 19% ~07s          
  |++++++++++                                        | 20% ~07s          
  |+++++++++++                                       | 21% ~07s          
  |+++++++++++                                       | 22% ~07s          
  |++++++++++++                                      | 23% ~07s          
  |++++++++++++                                      | 24% ~07s          
  |+++++++++++++                                     | 25% ~07s          
  |+++++++++++++                                     | 26% ~07s          
  |++++++++++++++                                    | 27% ~07s          
  |++++++++++++++                                    | 28% ~06s          
  |+++++++++++++++                                   | 29% ~06s          
  |+++++++++++++++                                   | 30% ~06s          
  |++++++++++++++++                                  | 31% ~06s          
  |++++++++++++++++                                  | 32% ~06s          
  |+++++++++++++++++                                 | 33% ~06s          
  |++++++++++++++++++                                | 34% ~06s          
  |++++++++++++++++++                                | 35% ~06s          
  |+++++++++++++++++++                               | 36% ~06s          
  |+++++++++++++++++++                               | 37% ~06s          
  |++++++++++++++++++++                              | 38% ~06s          
  |++++++++++++++++++++                              | 39% ~05s          
  |+++++++++++++++++++++                             | 40% ~05s          
  |+++++++++++++++++++++                             | 41% ~05s          
  |++++++++++++++++++++++                            | 42% ~05s          
  |++++++++++++++++++++++                            | 43% ~05s          
  |+++++++++++++++++++++++                           | 44% ~05s          
  |+++++++++++++++++++++++                           | 45% ~05s          
  |++++++++++++++++++++++++                          | 46% ~05s          
  |++++++++++++++++++++++++                          | 47% ~05s          
  |+++++++++++++++++++++++++                         | 48% ~05s          
  |+++++++++++++++++++++++++                         | 49% ~04s          
  |++++++++++++++++++++++++++                        | 51% ~04s          
  |++++++++++++++++++++++++++                        | 52% ~04s          
  |+++++++++++++++++++++++++++                       | 53% ~04s          
  |+++++++++++++++++++++++++++                       | 54% ~04s          
  |++++++++++++++++++++++++++++                      | 55% ~04s          
  |++++++++++++++++++++++++++++                      | 56% ~04s          
  |+++++++++++++++++++++++++++++                     | 57% ~04s          
  |+++++++++++++++++++++++++++++                     | 58% ~04s          
  |++++++++++++++++++++++++++++++                    | 59% ~04s          
  |++++++++++++++++++++++++++++++                    | 60% ~04s          
  |+++++++++++++++++++++++++++++++                   | 61% ~03s          
  |+++++++++++++++++++++++++++++++                   | 62% ~03s          
  |++++++++++++++++++++++++++++++++                  | 63% ~03s          
  |++++++++++++++++++++++++++++++++                  | 64% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~03s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~03s          
  |++++++++++++++++++++++++++++++++++                | 67% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~03s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~03s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~03s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~02s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~02s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 76% ~02s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~02s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 80% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=09s  
top5 <- ClusterMarkers %>% group_by(cluster) %>% top_n(n=5, wt = avg_log2FC)
DoHeatmap(seu, features = top5$gene, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.2')



#write.csv(ClusterMarkers, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/ClusterMarkers_neurons1_res025.csv")


write.csv(ClusterMarkers, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/ClusterMarkers_neurons1_res02.csv")
DimPlot(seu, group.by = 'RNA_snn_res.0.2', reduction = 'umap')

Get the most highly expressed genes in the total data (Neurons1)

Filters out specific genes


seu.ft <- seu[!grepl("MALAT1", rownames(seu)), ]
seu.ft <- seu.ft[!grepl("^MT-", rownames(seu.ft)), ]

Try to find doublets with doublet finder

remotes::install_github('chris-mcginnis-ucsf/DoubletFinder')
Skipping install of 'DoubletFinder' from a github remote, the SHA1 (67fb8b58) has not changed since last install.
  Use `force = TRUE` to force installation
suppressMessages(require(DoubletFinder))

Do the double cells have more genes than the singlet??


VlnPlot(seu.d, features = "nFeature_RNA", group.by = DF.name, pt.size = 0.1)

NA
NA

remove the doublets

dim(seu.d)
[1] 33538  1723
dim(seu)
[1] 33538  1833

Save the filtered, doublet removed Neurons object Re-run PCA for clustering


saveRDS(seu.d, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/NeuronsFilteredSeu28092022.RDS")

DAsubgroups data has not be re-processed Run standard workflow chunk

seu <- AIW60
seu <- NormalizeData(seu, normalization.method = "LogNormalize", scale.factor = 10000)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- FindVariableFeatures(seu, selection.method = "vst", nfeatures = 2000)
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- ScaleData(seu)
Centering and scaling data matrix

  |                                                                                                      
  |                                                                                                |   0%
  |                                                                                                      
  |================================================                                                |  50%
  |                                                                                                      
  |================================================================================================| 100%
seu <- RunPCA(seu)
PC_ 1 
Positive:  STMN2, DCX, INA, MAP2, SOX4, KIF5C, NCAM1, GAP43, SOX11, NSG2 
       ANK3, GPM6A, SYT1, TUBB2A, NRXN1, PKIA, NR2F1, STMN4, UCHL1, RTN1 
       TAGLN3, RUNX1T1, DPYSL3, NSG1, NEFM, PGM2L1, PRKAR2B, PBX1, POU2F2, ELAVL4 
Negative:  SPARC, ZFP36L1, VIM, TPBG, MDK, ANXA5, GNG5, CD9, CA2, CAST 
       ANXA2, HES1, FSTL1, NFIA, CD99, IGFBP2, TTR, IGFBP7, GSTP1, ID1 
       ID3, CYSTM1, PLTP, ZFP36L2, TRPM3, FAT1, COLEC12, B2M, SPARCL1, TMEM123 
PC_ 2 
Positive:  TTR, TPBG, IGFBP7, ANXA2, TRPM3, SLC7A8, CD9, SPINT2, CHCHD2, NFIA 
       SPARCL1, COLEC12, PPIC, PRNP, WFIKKN2, PIFO, BMP4, DMKN, LINC01088, ID1 
       MITF, CA2, ECEL1, SLC5A3, SERPINF1, CFAP126, PCP4, KRT18, SELENOP, CPVL 
Negative:  NUSAP1, TOP2A, MKI67, CENPF, PBK, CDK1, TPX2, NUF2, UBE2C, BIRC5 
       MAD2L1, CCNA2, ASPM, NCAPG, SPC25, PCLAF, CENPU, PIMREG, NDC80, KNL1 
       SMC4, KIF15, DLGAP5, SGO1, CDCA2, CDCA8, MIS18BP1, RRM2, CENPE, KIF11 
PC_ 3 
Positive:  TTYH1, PTPRZ1, NES, QKI, VIM, BOC, FGFBP3, HES5, SOX2, SLC1A3 
       RFX4, FAM181B, IGDCC3, FAM181A, EDNRB, LINC00461, PON2, RPS27L, VCAM1, CCND1 
       ARHGEF6, ZFP36L1, PLP1, JAG1, PCDH18, ITGB8, SMOC1, DLK1, TMEM38B, TFDP2 
Negative:  RTN1, STMN2, NSG2, GAP43, INA, PRKAR2B, MAPT, UCHL1, NRXN1, PKIA 
       TRPM3, IGFBP7, NSG1, C11orf88, NCAM1, SHTN1, DLGAP5, PCP4, SOBP, DCX 
       CFAP126, ANK3, TTR, NEK2, HIST1H4C, GPM6A, XPR1, CELF4, SPINT2, MITF 
PC_ 4 
Positive:  C11orf88, CAPSL, C1orf194, FAM81B, AKAP14, FAM183A, CFAP126, C9orf24, RSPH1, TCTEX1D1 
       ROPN1L, PIFO, C5orf49, CFAP52, DAW1, ARMC3, CCDC170, FAM216B, EFCAB1, MAP3K19 
       CP, SPAG6, CFAP45, AL357093.2, TEKT1, ANKRD66, MORN5, PTPRC, DYNLRB2, CFAP299 
Negative:  CNTNAP2, SYT4, ZIC1, APP, ZIC2, CBLN1, TNC, APCDD1, PTN, EPHA7 
       PAX6, SLITRK6, DSP, SPARCL1, WLS, ZFHX4, RSPO2, ATP1A2, CDK6, TXNIP 
       IL17RD, TPBG, AMER2, GDF10, ZIC4, PCDH9, WNT2B, HES1, GAP43, ITGA6 
PC_ 5 
Positive:  CALM1, TMSB4X, C11orf88, CKB, ACAT2, C1orf194, FGFBP3, C5orf49, HMGCS1, NR2F1 
       SCD, PTPRZ1, AKAP14, CAPSL, MSMO1, CFAP126, RPS2, IDI1, FAM81B, FDPS 
       FAM183A, PEG10, RSPH1, FDFT1, TUBA1B, GPM6B, ROPN1L, ARL4A, QKI, NTRK2 
Negative:  CCNB1, PLK1, UBE2C, BUB1, CDC20, ASPM, KIF20A, CENPA, CDCA8, DLGAP5 
       AURKA, KIF2C, CCNB2, NEK2, FAM83D, TTK, NUF2, PIF1, TPX2, KIF14 
       GTSE1, CDCA3, CDKN3, PIMREG, HMMR, CENPE, CDCA2, DEPDC1, CKAP2L, SGO2 
seu <- RunUMAP(seu, reduction = "pca", n.neighbors = 123, dims = 1:30)
Warning: The default method for RunUMAP has changed from calling Python UMAP via reticulate to the R-native UWOT using the cosine metric
To use Python UMAP via reticulate, set umap.method to 'umap-learn' and metric to 'correlation'
This message will be shown once per session
13:03:03 UMAP embedding parameters a = 0.9922 b = 1.112
13:03:03 Read 15339 rows and found 30 numeric columns
13:03:03 Using Annoy for neighbor search, n_neighbors = 123
13:03:03 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
13:03:04 Writing NN index file to temp file /var/folders/k4/khtkczkd5tn732ftjpwgtr240000gn/T//RtmphW80ig/file17bc7524a9002
13:03:04 Searching Annoy index using 1 thread, search_k = 12300
13:03:14 Annoy recall = 100%
13:03:14 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 123
13:03:16 Initializing from normalized Laplacian + noise (using irlba)
13:03:17 Commencing optimization for 200 epochs, with 2087112 positive edges
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
13:03:32 Optimization finished
DimPlot(seu, reduction = "umap")

Look at the DA data from Kamath

Annotate clusters Use: Organoid data, public brain data (LaManno, Lake, Mascako)

top10 <- head(VariableFeatures(DAsubtypes.sub), 10)
# plot variable features with and without labels
plot1 <- VariableFeaturePlot(DAsubtypes.sub)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
When using repel, set xnudge and ynudge to 0 for optimal results
plot2
Warning: Transformation introduced infinite values in continuous x-axis
Warning: Removed 9387 rows containing missing values (geom_point).

See how each looks on UMAP


DimPlot(seu.q, group.by = 'RNA_snn_res.1.2')

DimPlot(seu.q, group.by = 'RNA_snn_res.0.2')

DimPlot(seu.q, group.by = 'AIW60.pred')

DimPlot(seu.q, group.by = 'MBOAIW.pred')

DimPlot(seu.q, group.by = 'MBOAST23.pred')

NA
NA
FindClusters(seu.q, resolution = c(0, 0.2,0.4,0.6))
Error in FindClusters.Seurat(seu.q, resolution = c(0, 0.2, 0.4, 0.6)) : 
  Provided graph.name not present in Seurat object
NA

Redo find clusters


seu.q <- FindNeighbors(seu.q, dims = 1:25, k.param = 43)
Computing nearest neighbor graph
Computing SNN
seu.q <- FindClusters(seu.q, resolution = c(0,0.2,0.4,0.6))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 1.0000
Number of communities: 1
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.8573
Number of communities: 4
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7887
Number of communities: 6
Elapsed time: 0 seconds
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.7394
Number of communities: 7
Elapsed time: 0 seconds
seu.q <- FindClusters(seu.q, resolution = c(1.2))
Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck

Number of nodes: 1723
Number of edges: 145289

Running Louvain algorithm...
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Maximum modularity in 10 random starts: 0.6259
Number of communities: 10
Elapsed time: 0 seconds
library(clustree)
Loading required package: ggraph

Attaching package: ‘ggraph’

The following object is masked from ‘package:sp’:

    geometry
clustree(seu.q, prefix = "RNA_snn_res.")

DimPlot(seu.q)

Look at the predictions in the new clusters

Based on the 3 different predictions I can lable the cell types

0 - NPC or early neurons 1 - immature excitatory neurons 2 - NPC or early neurons 3 - RG or Oligos 4- Dopaminergic neurons - possibly early 5 - NPC or early neurons 6 - Radial GLia

I will also find markers and look at a list of neuronal markers

top5 <- ClusterMarkers %>% group_by(cluster) %>% top_n(n=5, wt = avg_log2FC)
DoHeatmap(seu.q, features = top5$gene, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = top5$gene, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: SAT1, MTRNR2L12, MT-ND2

write.csv(ClusterMarkers,"/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/Neurons1ClusterMarkers7.csv")

Explore some Gene expression levels

feature_list = c("MKI67","SOX2","POU5F1","DLX2","PAX6","SOX9","HES1","NES","RBFOX3","MAP2","NCAM1","CD24","GRIA2","GRIN2B","GABBR1","GAD1","GAD2","GABRA1","GABRB2","TH","ALDH1A1","LMX1B","NR4A2","CORIN","CALB1","KCNJ6","CXCR4","ITGA6","SLC1A3","CD44","AQP4","S100B", "PDGFRA","OLIG2","MBP","CLDN11","VIM","VCAM1")

DoHeatmap(seu.q, features = feature_list, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = feature_list, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: VCAM1, CLDN11, OLIG2, PDGFRA, CD44, SLC1A3, KCNJ6, CORIN, NR4A2, LMX1B, ALDH1A1, GABRA1, GAD2, GABBR1, NCAM1, RBFOX3, NES, SOX9, DLX2, POU5F1, MKI67

DotPlot(seu.q, features = feature_list) +RotatedAxis()


PD_poulin = c("TH","SLC6A3","SLC18A2","SOX6","NDNF","SNCG","ALDH1A1","CALB1","TACR2","SLC17A6","SLC32A1","OTX2","GRP","LPL","CCK","VIP")

DoHeatmap(seu.q, features = PD_poulin, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = PD_poulin, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: VIP, CCK, GRP, SLC32A1, TACR2, ALDH1A1, SNCG, NDNF, SOX6, SLC18A2, SLC6A3

DotPlot(seu.q, features = PD_poulin)+RotatedAxis()


ealryNeur = c("DCX","NEUROD1","TBR1")
proliferation = c("PCNA","MKI67")
neuralstem = c("SOX2","NES","PAX6","MASH1")

feature_list <- c("DCX","NEUROD1","TBR1","PCNA","MKI67","SOX2","NES","PAX6","MASH1")
DoHeatmap(seu.q, features = feature_list, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = feature_list, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: MASH1, NES, MKI67, PCNA

DotPlot(seu.q, features = feature_list)+RotatedAxis()
Warning in FetchData.Seurat(object = object, vars = features, cells = cells) :
  The following requested variables were not found: MASH1

# no proliferation marker expression  PCNA or MKI67
# cluster 4 DA neurons - shows early neuron marker and low PAX 4
# cluster 3 has higher SOX2 - neuroblast marker / NPC marker

mat_neuron = c("RBFOX3","SYP","DLG45","VAMP1","VAMP2","TUBB3","SYT1","BSN","HOMER1","SLC17A6") 
# NeuN is FOX3 - RBFOX3
# PSD95 also SP-90 or DLG4
# VGLUT2 is SLC17A6
DoHeatmap(seu.q, features = mat_neuron, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = mat_neuron, size = 3, angle = 90,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: HOMER1, BSN, TUBB3, VAMP1, DLG45, SYP, RBFOX3

# cluster 4 also show mature neuron markers
DotPlot(seu.q, features = mat_neuron)+RotatedAxis()
Warning in FetchData.Seurat(object = object, vars = features, cells = cells) :
  The following requested variables were not found: DLG45

# excitatory neuron markers
ex = c("GRIA2","GRIA1","GRIA4","GRIN1","GRIN2B","GRIN2A","GRIN3A","GRIN3","GRIP1","CAMK2A")
DoHeatmap(seu.q, features = ex, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = ex, size = 3, angle = 90, group.bar.height = 0.02,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: CAMK2A, GRIP1, GRIN3, GRIN3A, GRIN2A, GRIN1, GRIA4

DotPlot(seu.q, features = ex)+RotatedAxis()
Warning in FetchData.Seurat(object = object, vars = features, cells = cells) :
  The following requested variables were not found: GRIN3

# inhibitory neuron markers
inh = c("GAD1","GAD2", "GAT1","PVALB","GABR2","GABR1","GBRR1","GABRB2","GABRB1","GABRB3","GABRA6","GABRA1","GABRA4","TRAK2")
DoHeatmap(seu.q, features = inh, size=3, angle =90, group.bar.height = 0.02, group.by = 'RNA_snn_res.0.6')
Warning in DoHeatmap(seu.q, features = inh, size = 3, angle = 90, group.bar.height = 0.02,  :
  The following features were omitted as they were not found in the scale.data slot for the RNA assay: TRAK2, GABRA1, GABRA6, GABRB3, GABRB1, GBRR1, GABR1, GABR2, PVALB, GAT1, GAD2

DotPlot(seu.q, features = inh)+RotatedAxis()
Warning in FetchData.Seurat(object = object, vars = features, cells = cells) :
  The following requested variables were not found: GAT1, GABR2, GABR1, GBRR1

# cluster 4 is more excitatory than inhbitory but neither marker set has much expression 

Checkout the Enricher cell type libraries from

N1.c6 <- ClusterMarkers %>% filter(cluster == 6 & avg_log2FC > 0)
genes <- N1.c6$gene

N1.c6.Er <- enrichr(genes, databases = db)
Uploading data to Enrichr... Done.
  Querying Allen_Brain_Atlas_up... Done.
  Querying Descartes_Cell_Types_and_Tissue_2021... Done.
  Querying CellMarker_Augmented_2021... Done.
  Querying Azimuth_Cell_Types_2021... Done.
Parsing results... Done.
plotEnrich(N1.c6.Er[[1]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c6.Er[[2]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c6.Er[[3]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")

plotEnrich(N1.c6.Er[[4]], showTerms = 20, numChar = 40, y = "Count", orderBy = "P.value")


N1.Er.genes.1 <- N1.c6.Er[[1]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.1

N1.Er.genes.2 <- N1.c6.Er[[2]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.2

N1.Er.genes.3 <- N1.c6.Er[[3]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.3

N1.Er.genes.4 <- N1.c6.Er[[4]] %>% select(Term, Genes, Combined.Score)
N1.Er.genes.4
NA

Library of tissue cell types for up regulated genes per cluster 0 - hypothalmus, DA A13 1- neural plate, Radial Glia 2 - Neural stem 3 - stromal, astro OPC 4 - Neurons 5 - endothelial, pericyte 6 - maybe neurons maybe not

By the combined information - annotate the clusters in Neurons1

Idents(seu.q) <- 'RNA_snn_res.0.6'
cluster.ids <- c("ImmatureNeurons","Neurons","NPC","OPC-RG","DAneurons",
                 "Other","RG")
unique(seu.q$RNA_snn_res.0.6)
[1] 1 5 0 3 4 2 6
Levels: 0 1 2 3 4 5 6
names(cluster.ids) <- levels(seu.q)
seu.q <- RenameIdents(seu.q, cluster.ids)
seu.q$subgroups <- Idents(seu.q)

DimPlot(seu.q, reduction = "umap", label = TRUE, group.by = 'subgroups', repel = TRUE)



saveRDS(seu.q, "/Users/rhalenathomas/Documents/Data/scRNAseq/PhenoID/scRNAseqSorted/objs/Neuron1LabledSeu30092022.RDS")

Next Repeat everything for Neurons2

seu.ft <- subset(seu, subset = nFeature_RNA > 250 & nCount_RNA > 250 & nCount_RNA < 10000) 
seu.ft
An object of class Seurat 
33541 features across 17604 samples within 2 assays 
Active assay: RNA (33538 features, 0 variable features)
 1 other assay present: HTO

Doublet finder

suppressMessages(require(DoubletFinder))

# filtering out MALAT1 and mitochondrial genes

seu.ft <- seu.ft[!grepl("MALAT1", rownames(seu)), ]
seu.ft <- seu.ft[!grepl("^MT-", rownames(seu.ft)), ]

par(mar = c(4, 8, 2, 1))
C <- seu@assays$RNA@counts
C <- Matrix::t(Matrix::t(C)/Matrix::colSums(C)) * 100
most_expressed <- order(apply(C, 1, median), decreasing = T)[25:1]
Warning in asMethod(object) :
  sparse->dense coercion: allocating vector of size 8.7 GiB
Error: vector memory exhausted (limit reached?)
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQpTaW5nbGUgY2VsbCBzZXEgYWZ0ZXIgc29ydGluZyBmb3IgUGhlbm9JRAoKc2FtcGxlMSA9IE5ldXJvbnMxCnNhbXBsZTIgPSBOZXVyb25zMgpzYW1wbGUzID0gR2xpYTEgLSBBc3Ryb2N5dGVzIChDRDQ0KykKc2FtcGxlNCA9IEdsaWEyIC0gUmFkaWFsIEdsaWEgKENENDQtKQoKSW4gSFBDIEkgaGF2ZSBydW4gc3RlcHMgb2Ygc2NybmFib3ggKGN1c3RvbSBwaXBlbGluZSBpbiBwcm9ncmVzcykKMS4gQ2VsbCBSYW5nZXIgZm9yIGZlYXR1cmUgc2VxCjIuIENyZWF0ZSBTZXVyYXQgT2JqZWN0cyAKMy4gQXBwbHkgbWluaW11bSBmaWx0ZXJpbmcgYW5kIGNhbGN1bGF0ZSBwZXJjZW50IG1pdG9jaG9uZHJpYS4KCkkgaGF2ZSB0ZWNobmljYWwgMyByZXBsaWNhdGVzIHdpdGggaGFzaHRhZyBsYWJlbHMgYXQgdGhpcyBwb2ludCBJIGhhdmVuJ3QgeWV0IGRlbXVsdGlwbGV4IHRoZSBoYXNodGFncy4gVGhlIGRhdGEgaGVyZSB3aWxsIGJlIHRyZWF0ZWQgYXMgb25lIHNhbXBsZS4gIEkgc29ydGVkIHRocmVlIHNlcGFyYXRlIHNhbXBsZXMgYW5kIHBvb2xlZCB0aGVtIHRvZ2V0aGVyLiAKCgpgYGB7cn0KIyBzZXQgdXAgdGhlIGVudmlyb25tZW50CgpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeShkcGx5cikKbGlicmFyeShNYXRyaXgpCmxpYnJhcnkoZ2dwbG90MikKCnJtKGxpc3QgPSBscygpKQoKCmBgYAoKClJlYWQgaW4gdGhlIHNldXJhdCBvYmplY3RzIG1hZGUgaW4gY29tcHV0ZSBjYW5hZGEKCmBgYHtyfQoKIyB0aGlzIHNlZW1zIHRvIG5ldmVyIGxvYWQgSSdsbCB1c2Ugc3RlcCAzIG91dHB1dCB0aGF0IGhhcyBzb21lIGZpbHRlcmluZyAKIyBuRmVhdHVyZV9STkEgPiAxODAgYW5kIHBlcmNlbnQubXQgPCAyNQoKcGF0aHdheSA8LSAiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzLyIKCk5ldXJvbnMxIDwtIHJlYWRSRFMocGFzdGUocGF0aHdheSwic2V1MS5yZHMiLHNlcCA9ICIiKSkKTmV1cm9uczIgPC0gcmVhZFJEUyhwYXN0ZShwYXRod2F5LCJzZXUyLnJkcyIsc2VwID0gIiIpKQpHbGlhMSA8LSByZWFkUkRTKHBhc3RlKHBhdGh3YXksInNldTMucmRzIixzZXAgPSAiIikpCkdsaWEyIDwtIHJlYWRSRFMocGFzdGUocGF0aHdheSwic2V1NC5yZHMiLHNlcCA9ICIiKSkKCk5ldXJvbnMxCk5ldXJvbnMyCkdsaWExCkdsaWEyCgpgYGAKCgpIYXZlIGEgbG9vayBhdCB0aGUgb2JqZWN0cyB0aGF0IGFscmVhZHkgaGF2ZSBzb21lIGZpbHRlcmluZwoKClNlZSB0aGUgdmlvbGluIHBsb3RzIAoKYGBge3J9CgpWbG5QbG90KE5ldXJvbnMxLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQoKVmxuUGxvdChOZXVyb25zMSwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiksIHkubWF4ID0gNTAwKQpWbG5QbG90KE5ldXJvbnMxLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuQ291bnRfUk5BIiksIHkubWF4ID0gMjAwMCkKCgoKIyBmaWx0ZXIgbW9yZSBjZWxscwoKTmV1cm9uMS5mdCA8LSBzdWJzZXQoTmV1cm9uczEsIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IDI1MCAmIG5Db3VudF9STkEgPiAyNTAgJiBuQ291bnRfUk5BIDwgMTAwMDApIApOZXVyb24xLmZ0CgojIDMzNTQxIGZlYXR1cmVzIGFjcm9zcyAxODMzIHNhbXBsZXMKCgpgYGAKCk5ldXJvbnMgMiAtIENENTYrKwoKYGBge3J9CgpWbG5QbG90KE5ldXJvbnMyLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQpWbG5QbG90KE5ldXJvbnMyLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSwgeS5tYXggPSA1MDApClZsblBsb3QoTmV1cm9uczIsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIpLCB5Lm1heCA9IDEwMDApClZsblBsb3QoTmV1cm9uczIsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5Db3VudF9STkEiKSwgeS5tYXggPSAyMDAwKQoKCgojIGZpbHRlciBtb3JlIGNlbGxzCgpOZXVyb24yLmZ0IDwtIHN1YnNldChOZXVyb25zMiwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BID4gNTAwICYgbkNvdW50X1JOQSA+IDUwMCAmIG5Db3VudF9STkEgPCAxMDAwMCkgCk5ldXJvbjIuZnQKCgoKYGBgCgpHbGlhMSAtIEFzdHJvY3l0ZSBkYXRhCgpgYGB7cn0KClZsblBsb3QoR2xpYTEsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiKSwgbmNvbCA9IDMpCgpWbG5QbG90KEdsaWExLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSwgeS5tYXggPSA1MDAwKQpWbG5QbG90KEdsaWExLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSwgeS5tYXggPSAxMDAwKQpWbG5QbG90KEdsaWExLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuQ291bnRfUk5BIiksIHkubWF4ID0gMTAwMCkKVmxuUGxvdChHbGlhMSwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkNvdW50X1JOQSIpLCB5Lm1heCA9IDEyMDAwKQoKCiMgZXh0cmVtZSBmaWx0ZXIKCkdsaWExLmZ0IDwtIHN1YnNldChHbGlhMSwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BID4gNTAwICYgbkNvdW50X1JOQSA+IDMwMCAmIG5Db3VudF9STkEgPCAxMDAwMCkgCkdsaWExLmZ0CkdsaWExCgpWbG5QbG90KEdsaWExLmZ0LCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQoKCgoKCmBgYAoKCkdsaWEyIC0gUmFkaWFsIEdsaWEKCmBgYHtyfQoKIyMgRmlsdGVyIEdsaWEgMgpWbG5QbG90KEdsaWEyLCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiLCAibkNvdW50X1JOQSIsICJwZXJjZW50Lm10IiksIG5jb2wgPSAzKQoKVmxuUGxvdChHbGlhMiwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiksIHkubWF4ID0gNTAwMCkKVmxuUGxvdChHbGlhMiwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiksIHkubWF4ID0gMTAwMCkKVmxuUGxvdChHbGlhMiwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkNvdW50X1JOQSIpLCB5Lm1heCA9IDEwMDApClZsblBsb3QoR2xpYTIsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5Db3VudF9STkEiKSwgeS5tYXggPSAxMjAwMCkKCgojIGV4dHJlbWUgZmlsdGVyCgpHbGlhMi5mdCA8LSBzdWJzZXQoR2xpYTEsIHN1YnNldCA9IG5GZWF0dXJlX1JOQSA+IDUwMCAmIG5Db3VudF9STkEgPiA1MDAgJiBuQ291bnRfUk5BIDwgMTAwMDApIApHbGlhMi5mdAoKClZsblBsb3QoR2xpYTEuZnQsIHB0LnNpemUgPSAwLjEwLCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiKSwgbmNvbCA9IDMpCgojIHRoZXJlIGFyZSBzbyBtYW55IHN1cG9zZWQgY2VsbHMgSSBhbSBjb25jZXJuZWQgdGhlIGhpZ2ggcmVhZCBjZWxscyBhcmUgYWN0dWFsbHkgZG91YmxldHMuIAoKCgpgYGAKCgpBbmFseXplIGVhY2ggZGF0YXNldCAtIGdldCBjbHVzdGVycyAKCmBgYHtyfQoKIyBjbHVzdGVyIHRoZSBuZXVyb25zCnNldSA8LSBOZXVyb24xLmZ0CnNldSRvcmlnLmlkZW50IDwtICdOZXVyb25zMScKCnNldSA8LSBOb3JtYWxpemVEYXRhKHNldSwgbm9ybWFsaXphdGlvbi5tZXRob2QgPSAiTG9nTm9ybWFsaXplIiwgc2NhbGUuZmFjdG9yID0gMTAwMDApCnNldSA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhzZXUsIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCkKIyBJZGVudGlmeSB0aGUgMTAgbW9zdCBoaWdobHkgdmFyaWFibGUgZ2VuZXMKdG9wMTAgPC0gaGVhZChWYXJpYWJsZUZlYXR1cmVzKHNldSksIDEwKQojIHBsb3QgdmFyaWFibGUgZmVhdHVyZXMgd2l0aCBhbmQgd2l0aG91dCBsYWJlbHMKcGxvdDEgPC0gVmFyaWFibGVGZWF0dXJlUGxvdChzZXUpCnBsb3QyIDwtIExhYmVsUG9pbnRzKHBsb3QgPSBwbG90MSwgcG9pbnRzID0gdG9wMTAsIHJlcGVsID0gVFJVRSkKCgoKc2V1IDwtIFNjYWxlRGF0YShzZXUpCnNldSA8LSBSdW5QQ0Eoc2V1KQpJZGVudHMoc2V1KSA8LSAnb3JpZy5pZGVudCcKcGxvdCA8LSBEaW1QbG90KHNldSwgcmVkdWN0aW9uID0gInBjYSIpCgoKcGxvdDMgPC0gRWxib3dQbG90KHNldSxuZGltcyA9IDUwKQpwbG90MwoKcGxvdDIKcGxvdAoKCgpgYGAKCmBgYHtyfQoKIyB1bWFwCgpzZXUgPC0gUnVuVU1BUChzZXUsIHJlZHVjdGlvbiA9ICJwY2EiLCBuLm5laWdoYm9ycyA9IDQzLCBkaW1zID0gMToyNSkKRGltUGxvdChzZXUsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAib3JpZy5pZGVudCIpCgoKCmBgYAoKTWFrZSB0aGUgY2x1c3RlcnMgTmV1cm9uczEKCmBgYHtyfQoKc2V1IDwtIEZpbmROZWlnaGJvcnMoc2V1LCBkaW1zID0gMToyNSwgay5wYXJhbSA9IDQzKQpzZXUgPC0gRmluZENsdXN0ZXJzKHNldSwgcmVzb2x1dGlvbiA9IGMoMCwwLjIsMC4yNSwwLjUsMC44KSkKc2V1IDwtIEZpbmRDbHVzdGVycyhzZXUsIHJlc29sdXRpb24gPSBjKDEuMikpCgpsaWJyYXJ5KGNsdXN0cmVlKQpjbHVzdHJlZShzZXUsIHByZWZpeCA9ICJSTkFfc25uX3Jlcy4iKQpEaW1QbG90KHNldSkKCmBgYAoKYGBge3J9CiMgbG9vayBhIGxvdCBhdCB0aGUgY2x1c2VycwoKVmxuUGxvdChzZXUsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBncm91cC5ieSA9ICdzZXVyYXRfY2x1c3RlcnMnLCBuY29sID0gMSkKIyB0aGVzZSBjZWxscyBtaWdodCBiZSBncm91cGluZyBieSAtIGhvdyBtdWNoIE1UIGFuZCBudW1iZXIgb2YgRmVhdHVyZXMKIyBjbHVzdGVycyA0LDUsNiBoYXZlIG1vcmUgZmVhdHVyZXMKClZsblBsb3Qoc2V1LCBmZWF0dXJlcyA9IGMoIm5GZWF0dXJlX1JOQSIsICJuQ291bnRfUk5BIiwgInBlcmNlbnQubXQiKSwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC4yNScsIG5jb2wgPSAxKQojIGhlcmUgY2x1c3RlciAzIGhhcyBoaWdoZXIgZXhwcmVzc2lvbiwgY2x1c3RlciAxIGFuZCA0IGhhdmUgc2ltaWxhciBGZWF0dXJlcyBSTkEKIyBjbHVzdGVyIDAgaGFzIGhpZ2hlciBwZXJjZW50IE1UIGxldmVscwoKVmxuUGxvdChzZXUsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjUnLCBuY29sID0gMSkKVmxuUGxvdChzZXUsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjInLCBuY29sID0gMSkKIyBub3cgb25seSBjbHVzdGVyIDAgaGF2ZSBoaWdoIE1UIGFuZCBsb3cgZmVhdHVyZXMsIGNsdXN0ZXJzIDEsMiwzIGhhdmUgc2ltaXVsYXIgUk5BIGFuZCBDb3VudHMKCmBgYAoKRmluZCB0aGUgY2x1c3RlciBtYXJrZXJzIGZvciBOZXVyb25zMQoKYGBge3J9CklkZW50cyhzZXUpIDwtICdSTkFfc25uX3Jlcy4wLjInCkNsdXN0ZXJNYXJrZXJzIDwtIEZpbmRBbGxNYXJrZXJzKHNldSkKCnRvcDUgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbihuPTUsIHd0ID0gYXZnX2xvZzJGQykKRG9IZWF0bWFwKHNldSwgZmVhdHVyZXMgPSB0b3A1JGdlbmUsIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC4yJykKCgojd3JpdGUuY3N2KENsdXN0ZXJNYXJrZXJzLCAiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9DbHVzdGVyTWFya2Vyc19uZXVyb25zMV9yZXMwMjUuY3N2IikKCgp3cml0ZS5jc3YoQ2x1c3Rlck1hcmtlcnMsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9QaGVub0lEL3NjUk5Bc2VxU29ydGVkL0NsdXN0ZXJNYXJrZXJzX25ldXJvbnMxX3JlczAyLmNzdiIpCgpgYGAKCmBgYHtyfQpEaW1QbG90KHNldSwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC4yJywgcmVkdWN0aW9uID0gJ3VtYXAnKQoKYGBgCgoKR2V0IHRoZSBtb3N0IGhpZ2hseSBleHByZXNzZWQgZ2VuZXMgaW4gdGhlIHRvdGFsIGRhdGEgKE5ldXJvbnMxKQoKCmBgYHtyfQoKcGFyKG1hciA9IGMoNCwgOCwgMiwgMSkpCkMgPC0gc2V1QGFzc2F5cyRSTkFAY291bnRzCkMgPC0gTWF0cml4Ojp0KE1hdHJpeDo6dChDKS9NYXRyaXg6OmNvbFN1bXMoQykpICogMTAwCm1vc3RfZXhwcmVzc2VkIDwtIG9yZGVyKGFwcGx5KEMsIDEsIG1lZGlhbiksIGRlY3JlYXNpbmcgPSBUKVsyNToxXQpib3hwbG90KGFzLm1hdHJpeCh0KENbbW9zdF9leHByZXNzZWQsIF0pKSwgY2V4ID0gMC4xLCBsYXMgPSAxLCB4bGFiID0gIiUgdG90YWwgY291bnQgcGVyIGNlbGwiLAogICAgY29sID0gKHNjYWxlczo6aHVlX3BhbCgpKSgyNSlbMToyNV0sIGhvcml6b250YWwgPSBUUlVFKQoKIyBsaWtlIGluIHRoZSB0dXRvcmlhbCBJJ20gZm9sbG93aW5nIE1BTEFUMSBpcyB0aGUgdG9wIG1vc3QgZXhwcmVzc2VkIGdlbmUuICBUaGUgdG9wIGdlbmVzIGFyZSBhIGxvdCBvZiBNVCBhbmQgUmlib3NvbWFsIGdlbmVzCgpzZXVbWyJwZXJjZW50LnJiIl1dIDwtIFBlcmNlbnRhZ2VGZWF0dXJlU2V0KHNldSwgcGF0dGVybiA9ICJeUlAiKQoKVmxuUGxvdChzZXUsIGZlYXR1cmVzID0gInBlcmNlbnQucmIiLCBncm91cC5ieSA9ICJSTkFfc25uX3Jlcy4wLjIiKQoKCgpgYGAKCkZpbHRlcnMgb3V0IHNwZWNpZmljIGdlbmVzCgpgYGB7cn0KCnNldS5mdCA8LSBzZXVbIWdyZXBsKCJNQUxBVDEiLCByb3duYW1lcyhzZXUpKSwgXQpzZXUuZnQgPC0gc2V1LmZ0WyFncmVwbCgiXk1ULSIsIHJvd25hbWVzKHNldS5mdCkpLCBdCgojIHRoaXMgZmlsdGVyZWQgb2JqZWN0IG1pZ2h0IGNsdXN0ZXIgZGlmZmVyZW50bHkKIyBmb3Igbm93IEknbSBnb2luZyB0byBtb3ZlIG9uIHRvIGRvdWJsZXQgZGV0ZWN0aW9uCgoKYGBgCgoKClRyeSB0byBmaW5kIGRvdWJsZXRzIHdpdGggZG91YmxldCBmaW5kZXIKCmBgYHtyfQpyZW1vdGVzOjppbnN0YWxsX2dpdGh1YignY2hyaXMtbWNnaW5uaXMtdWNzZi9Eb3VibGV0RmluZGVyJykKc3VwcHJlc3NNZXNzYWdlcyhyZXF1aXJlKERvdWJsZXRGaW5kZXIpKQoKCmBgYAoKYGBge3J9CgpzZXUuZCA9IEZpbmRWYXJpYWJsZUZlYXR1cmVzKHNldSwgdmVyYm9zZSA9IEYpCnNldS5kID0gU2NhbGVEYXRhKHNldS5kLCB2YXJzLnRvLnJlZ3Jlc3MgPSBjKCJuRmVhdHVyZV9STkEiLCAicGVyY2VudC5tdCIpLAogICAgdmVyYm9zZSA9IEYpCnNldS5kID0gUnVuUENBKHNldS5kLCB2ZXJib3NlID0gRiwgbnBjcyA9IDIwKQpzZXUuZCA9IFJ1blVNQVAoc2V1LmQsIGRpbXMgPSAxOjEwLCB2ZXJib3NlID0gRikKCm5FeHAgPC0gcm91bmQobmNvbChzZXUuZCkgKiAwLjA2KSAgIyBleHBlY3QgNiUgZG91YmxldHMKc2V1LmQgPC0gZG91YmxldEZpbmRlcl92MyhzZXUuZCwgcE4gPSAwLjI1LCBwSyA9IDAuMDksIG5FeHAgPSBuRXhwLCBQQ3MgPSAxOjEwKQoKCiMgbmFtZSBvZiB0aGUgREYgcHJlZGljdGlvbiBjYW4gY2hhbmdlLCBzbyBleHRyYWN0IHRoZSBjb3JyZWN0IGNvbHVtbiBuYW1lLgpERi5uYW1lID0gY29sbmFtZXMoc2V1LmRAbWV0YS5kYXRhKVtncmVwbCgiREYuY2xhc3NpZmljYXRpb24iLCBjb2xuYW1lcyhzZXUuZEBtZXRhLmRhdGEpKV0KCgoKY293cGxvdDo6cGxvdF9ncmlkKG5jb2wgPSAyLCBEaW1QbG90KHNldS5kLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikgKyBOb0F4ZXMoKSwKICAgIERpbVBsb3Qoc2V1LmQsIGdyb3VwLmJ5ID0gREYubmFtZSkgKyBOb0F4ZXMoKSkKCgpgYGAKCkRvIHRoZSBkb3VibGUgY2VsbHMgaGF2ZSBtb3JlIGdlbmVzIHRoYW4gdGhlIHNpbmdsZXQ/PwoKYGBge3J9CgpWbG5QbG90KHNldS5kLCBmZWF0dXJlcyA9ICJuRmVhdHVyZV9STkEiLCBncm91cC5ieSA9IERGLm5hbWUsIHB0LnNpemUgPSAwLjEpCgoKYGBgCgojIHJlbW92ZSB0aGUgZG91YmxldHMKCmBgYHtyfQoKc2V1LmQgPC0gc2V1LmRbLCBzZXUuZEBtZXRhLmRhdGFbLCBERi5uYW1lXT09ICJTaW5nbGV0Il0KZGltKHNldS5kKQpkaW0oc2V1KQoKIyByZW1vdmVkIGFib3V0IDEwMCBjZWxscwoKCgoKYGBgCgoKU2F2ZSB0aGUgZmlsdGVyZWQsIGRvdWJsZXQgcmVtb3ZlZCBOZXVyb25zIG9iamVjdCAKUmUtcnVuIFBDQSBmb3IgY2x1c3RlcmluZyAKCmBgYHtyfQoKc2F2ZVJEUyhzZXUuZCwgIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvb2Jqcy9OZXVyb25zRmlsdGVyZWRTZXUyODA5MjAyMi5SRFMiKQoKYGBgCgoKREFzdWJncm91cHMgZGF0YSBoYXMgbm90IGJlIHJlLXByb2Nlc3NlZApSdW4gc3RhbmRhcmQgd29ya2Zsb3cgY2h1bmsKCmBgYHtyfQoKI3NldSA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9NYWNvc2tvX0RhdGEvUERfZGEuUmRzIikKI3NldSA8LSBBSVc2MApzZXUgPC0gTm9ybWFsaXplRGF0YShzZXUsIG5vcm1hbGl6YXRpb24ubWV0aG9kID0gIkxvZ05vcm1hbGl6ZSIsIHNjYWxlLmZhY3RvciA9IDEwMDAwKQpzZXUgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoc2V1LCBzZWxlY3Rpb24ubWV0aG9kID0gInZzdCIsIG5mZWF0dXJlcyA9IDIwMDApCnNldSA8LSBTY2FsZURhdGEoc2V1KQpzZXUgPC0gUnVuUENBKHNldSkKc2V1IDwtIFJ1blVNQVAoc2V1LCByZWR1Y3Rpb24gPSAicGNhIiwgbi5uZWlnaGJvcnMgPSAxNTksIGRpbXMgPSAxOjMwKQpEaW1QbG90KHNldSwgcmVkdWN0aW9uID0gInVtYXAiKQoKI3NhdmVSRFMoc2V1LCAiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvTWFjb3Nrb19EYXRhL0RBc3ViZ3JvdXBzX3Byb2Nlc3NlZC5SZHMiKQoKI25vdGUgbXkgQUlXIDYwIGRheXMgZGF0YSBhbHNvIGRpZG4ndCBoYXZlIHRoZSBQQ0Egc2F2ZWQgCiMgcmFuIGNvZGUgY2h1bmNrIHdpdGggbi5uZWlnaGJvcnMgPSAxMjMgCiMgc2F2ZVJEUyhzZXUsICIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9BSVd0cmlvNjBkYXlzL0FXSTAwMlBhcmtpbktPUGlua0tPNjBkYXlzX2xhYmVsc18xNDA1MjAyMi5yZHMiKQoKCmBgYAoKCkxvb2sgYXQgdGhlIERBIGRhdGEgZnJvbSBLYW1hdGgKCmBgYHtyfQpEQXN1YnR5cGVzIDwtIFJ1blVNQVAoREFzdWJ0eXBlcywgcmVkdWN0aW9uID0gInBjYSIsIG4ubmVpZ2hib3JzID0gMTU5LCBkaW1zID0gMTozMCwgbWluLmRpc3QgPSAwLjI1LCBzcHJlYWQgPSAyKQoKRGltUGxvdChEQXN1YnR5cGVzKQpWbG5QbG90KERBc3VidHlwZXMsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwibkNvdW50X1JOQSIpKQojIHRoZXJlIGlzIHZlcnkgaGlnaCBSTkEgZmVhdHVyZXMgYW5kIGNvdW50cwoKCgpgYGAKCgpBbm5vdGF0ZSBjbHVzdGVycwpVc2U6IE9yZ2Fub2lkIGRhdGEsIHB1YmxpYyBicmFpbiBkYXRhIChMYU1hbm5vLCBMYWtlLCBNYXNjYWtvKQoKCmBgYHtyfQoKIyB0aGlzIGlzIHNvbWUgcmVmZXJlbmNlIGRhdGEKCiMgU05DQSBhbmQgY29udHJvbCBtaWRicmFpbiBvcmdhbm9pZHMgMTY1IGRheXMgaW4gY3VsdHVyZQpNQk8gPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvQVNUMjNfQnJhaW5Db21tL01CT2NsdXN0ZXJzX25hbWVzMjkwNzIwMjEucmRzIikKCiMgTWlkYnJhaW4gIEFJVzAwMiAxMjAgZGF5cyBpbiBjdWx0dXJlCkFJV01CTyA8LSByZWFkUkRTKCIvVXNlcnMvcmhhbGVuYXRob21hcy9Eb2N1bWVudHMvRGF0YS9zY1JOQXNlcS9BSVd0cmlvMTIwZGF5cy9NT2ludGVncmF0ZWRDbHVzdGVySzEyM3JlczAuOC5uYW1lc19ub3YxNl8yMDIxIikKCiMgTWlkYnJhaW4gQUlXMDAyIDYwIGRheXMgaW4gY3VsdHVyZQoKQUlXNjAgPC0gcmVhZFJEUygiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvQUlXdHJpbzYwZGF5cy9BV0kwMDJQYXJraW5LT1BpbmtLTzYwZGF5c19sYWJlbHNfMTQwNTIwMjIucmRzIikKCiMgREEgbmV1cm9uIHN1YnR5cGVzIGZyb20gcG9zdG1vcnRlbSBicmFpbiBLYW1hdGggZXQgYWwgMjAyMgpEQXN1YnR5cGVzIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL01hY29za29fRGF0YS9EQXN1Ymdyb3Vwc19wcm9jZXNzZWQuUmRzIikKCgojIHF1ZXJ5CnNldS5xIDwtIHJlYWRSRFMoIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvb2Jqcy9OZXVyb25zRmlsdGVyZWRTZXUyODA5MjAyMi5SRFMiKQoKCiNmaXJzdCBwcmVkaWN0IHdpdGggdGhlIE1CTyBkYXRhCklkZW50cyhNQk8pIDwtICJjbHVzdGVyX2xhYmVscyIKRGVmYXVsdEFzc2F5KE1CTykgPC0gIlJOQSIKCiMgZmluZCB0aGUgcmVmZXJlbmNlIGFuY2hvcnMKcHJpbnQoImZpbmRpbmcgcmVmZXJlbmNlIGFuY2hvcnMiKQphbmNob3JzIDwtIEZpbmRUcmFuc2ZlckFuY2hvcnMocmVmZXJlbmNlID0gTUJPICxxdWVyeSA9IHNldS5xLCBkaW1zID0gMToyNSkKcHJpbnQoImdldHRpbmcgcHJlZGljdGlvbnMiKQpwcmVkaWN0aW9ucyA8LSBUcmFuc2ZlckRhdGEoYW5jaG9yc2V0ID0gYW5jaG9ycywgcmVmZGF0YSA9IE1CTyRjbHVzdGVyX2xhYmVscykKc2V1LnEgPC0gQWRkTWV0YURhdGEoc2V1LnEsIG1ldGFkYXRhID0gcHJlZGljdGlvbnMpCnByaW50KHRhYmxlKHNldS5xJHByZWRpY3RlZC5pZCkpCgpJZGVudHMoc2V1LnEpIDwtICdwcmVkaWN0ZWQuaWQnCiMgYWRkIG5ldyBkYXRhc2xvdCBmb3IgTUJPIHByZWRpY3RlZCBJRCB0byBtYWtlIHRoZSBuZXh0IHByZWRpY3Rpb24Kc2V1LnEkTUJPQVNUMjMucHJlZCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ01CT0FTVDIzLnByZWQnLCBsYWJlbCA9IFRSVUUpCiAKIyMgY2hlY2sgdGhlIHByb3BvcnRpb24gb2YgY2VsbCB0eXBlcyBwcmVkaWN0ZWQgaW4gZWFjaCBjbHVzdGVyCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRwcmVkaWN0ZWQuaWQpKQpwci50LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHByb3AudGFibGUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRwcmVkaWN0ZWQuaWQpKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKCgojIHRyeSBiYXIgY2hhcnQKZ2dwbG90KHQubGFibGVzLCBhZXMoeSA9IEZyZXEsIHggPSBWYXIxLCBmaWxsID0gVmFyMikpICsgZ2VvbV9iYXIocG9zaXRpb24gPSAic3RhY2siLCBzdGF0PSAiaWRlbnRpdHkiKQoKIyBjbHVzdGVycyBkb24ndCBicmVhayB1cCBieSB0aGUgcHJlZGljdGVkIGNlbGwgdHlwZXMKCiMjIyMjIyMjIyMjIyBhbm90aGVyIHByZWRpY3Rpb25zIG5vdyB1c2luZyB0aGUgQUlXIG9yZ2Fub2lkcwoKSWRlbnRzKEFJV01CTykgPC0gInJlczA4bmFtZXMiCkRlZmF1bHRBc3NheShBSVdNQk8pIDwtICJSTkEiCgphbmNob3JzIDwtIEZpbmRUcmFuc2ZlckFuY2hvcnMocmVmZXJlbmNlID0gQUlXTUJPICxxdWVyeSA9IHNldS5xLCBkaW1zID0gMToyNSkKcHJpbnQoImdldHRpbmcgcHJlZGljdGlvbnMiKQpwcmVkaWN0aW9ucyA8LSBUcmFuc2ZlckRhdGEoYW5jaG9yc2V0ID0gYW5jaG9ycywgcmVmZGF0YSA9IEFJV01CTyRyZXMwOG5hbWVzKQpzZXUucSA8LSBBZGRNZXRhRGF0YShzZXUucSwgbWV0YWRhdGEgPSBwcmVkaWN0aW9ucykKcHJpbnQodGFibGUoc2V1LnEkcHJlZGljdGVkLmlkKSkKCklkZW50cyhzZXUucSkgPC0gJ3ByZWRpY3RlZC5pZCcKIyBhZGQgbmV3IGRhdGFzbG90IGZvciBNQk8gcHJlZGljdGVkIElEIHRvIG1ha2UgdGhlIG5leHQgcHJlZGljdGlvbgpzZXUucSRNQk9BSVcucHJlZCA8LSBJZGVudHMoc2V1LnEpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ01CT0FJVy5wcmVkJywgbGFiZWwgPSBUUlVFKQogCiMjIGNoZWNrIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGwgdHlwZXMgcHJlZGljdGVkIGluIGVhY2ggY2x1c3Rlcgp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkKcHIudC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgoKIyB0cnkgYmFyIGNoYXJ0CmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikKCiMgdGhlIHByZWRpY3RlZCBjZWxsIHR5cGVzIG1ha2UgbW9yZSBzZW5zZSBmcm9tIHRoZSBBSVcwMDIgb3JnYW5vaWQKIyBub3cgcHJlZGljdCB3aXRoIHRoZSBBSVcwMDIgNjAgZGF5cyBvcmdhbm9pZAoKSWRlbnRzKEFJVzYwKSA8LSAiY2x1c3Rlci5pZHMiCkRlZmF1bHRBc3NheShBSVc2MCkgPC0gIlJOQSIKCmFuY2hvcnMgPC0gRmluZFRyYW5zZmVyQW5jaG9ycyhyZWZlcmVuY2UgPSBBSVc2MCwgcXVlcnkgPSBzZXUucSwgZGltcyA9IDE6MjUpCnByaW50KCJnZXR0aW5nIHByZWRpY3Rpb25zIikKcHJlZGljdGlvbnMgPC0gVHJhbnNmZXJEYXRhKGFuY2hvcnNldCA9IGFuY2hvcnMsIHJlZmRhdGEgPSBBSVc2MCRjbHVzdGVyLmlkcykgCnNldS5xIDwtIEFkZE1ldGFEYXRhKHNldS5xLCBtZXRhZGF0YSA9IHByZWRpY3Rpb25zKQpwcmludCh0YWJsZShzZXUucSRwcmVkaWN0ZWQuaWQpKQoKSWRlbnRzKHNldS5xKSA8LSAncHJlZGljdGVkLmlkJwojIGFkZCBuZXcgZGF0YXNsb3QgZm9yIE1CTyBwcmVkaWN0ZWQgSUQgdG8gbWFrZSB0aGUgbmV4dCBwcmVkaWN0aW9uCnNldS5xJEFJVzYwLnByZWQgPC0gSWRlbnRzKHNldS5xKQpEaW1QbG90KHNldS5xLCBncm91cC5ieSA9ICdBSVc2MC5wcmVkJywgbGFiZWwgPSBUUlVFKQogCiMjIGNoZWNrIHRoZSBwcm9wb3J0aW9uIG9mIGNlbGwgdHlwZXMgcHJlZGljdGVkIGluIGVhY2ggY2x1c3Rlcgp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkKcHIudC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZShwcm9wLnRhYmxlKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuMiwgc2V1LnEkcHJlZGljdGVkLmlkKSkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCgoKIyB0cnkgYmFyIGNoYXJ0CmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikKCiMgc2F2ZSBvamJlY3Qgd2l0aCBwcmVkaWNpdG9ucwpzYXZlUkRTKHNldS5xLCAiL1VzZXJzL3JoYWxlbmF0aG9tYXMvRG9jdW1lbnRzL0RhdGEvc2NSTkFzZXEvUGhlbm9JRC9zY1JOQXNlcVNvcnRlZC9vYmpzL05ldXJvbnNGaWx0ZXJlZFNldTI4MDkyMDIyLlJEUyIpCgoKCmBgYAoKYGBge3J9CiMgY29tcGFyZSB0aGUgdGhyZWUgcHJlZGljdGlvbnMKI0FTVDIzIHZzIEFJVzYwCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkTUJPQVNUMjMucHJlZCwgc2V1LnEkQUlXNjAucHJlZCkpCnByLnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUocHJvcC50YWJsZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjIsIHNldS5xJHByZWRpY3RlZC5pZCkpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQoKIyB0cnkgYmFyIGNoYXJ0CmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikgKyBSb3RhdGVkQXhpcygpCgojQVNUMjMgdnMgQUlXMTIwCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkTUJPQVNUMjMucHJlZCwgc2V1LnEkTUJPQUlXLnByZWQpKQpwci50LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHByb3AudGFibGUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRwcmVkaWN0ZWQuaWQpKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKCiMgdHJ5IGJhciBjaGFydApnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKQoKCiMgQUlXNjAgdnMgQUlXMTIwCnQubGFibGVzIDwtIGFzLmRhdGEuZnJhbWUodGFibGUoc2V1LnEkQUlXNjAucHJlZCwgc2V1LnEkTUJPQUlXLnByZWQpKQpwci50LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHByb3AudGFibGUodGFibGUoc2V1LnEkUk5BX3Nubl9yZXMuMC4yLCBzZXUucSRwcmVkaWN0ZWQuaWQpKSkKdC5sYWJsZXMkRnJlcSA8LSBhcy5kb3VibGUodC5sYWJsZXMkRnJlcSkKCiMgdHJ5IGJhciBjaGFydApnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKQoKCmBgYAoKU2VlIGhvdyBlYWNoIGxvb2tzIG9uIFVNQVAKCmBgYHtyfQoKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMS4yJykKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC4yJykKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnQUlXNjAucHJlZCcpCkRpbVBsb3Qoc2V1LnEsIGdyb3VwLmJ5ID0gJ01CT0FJVy5wcmVkJykKRGltUGxvdChzZXUucSwgZ3JvdXAuYnkgPSAnTUJPQVNUMjMucHJlZCcpCgoKYGBgCgpgYGB7cn0KCiMgcmVkbyBjbHVzdGVycwpzZXUucSA8LSBOb3JtYWxpemVEYXRhKHNldS5xLCBub3JtYWxpemF0aW9uLm1ldGhvZCA9ICJMb2dOb3JtYWxpemUiLCBzY2FsZS5mYWN0b3IgPSAxMDAwMCkKc2V1LnEgPC0gRmluZFZhcmlhYmxlRmVhdHVyZXMoc2V1LnEsIHNlbGVjdGlvbi5tZXRob2QgPSAidnN0IiwgbmZlYXR1cmVzID0gMjAwMCkKc2V1LnEgPC0gU2NhbGVEYXRhKHNldS5xKQpzZXUucSA8LSBSdW5QQ0Eoc2V1LnEpCnNldS5xIDwtIFJ1blVNQVAoc2V1LnEsIHJlZHVjdGlvbiA9ICJwY2EiLCBuLm5laWdoYm9ycyA9IDI1LCBkaW1zID0gMTozMCwgbWluLmRpc3QgPSAwLjI1LCBzcHJlYWQgPSAyKQpEaW1QbG90KHNldS5xLCByZWR1Y3Rpb24gPSAidW1hcCIsIGdyb3VwLmJ5ID0gJ01CT0FJVy5wcmVkJykKCgoKCgpgYGAKCgpSZWRvIGZpbmQgY2x1c3RlcnMKCmBgYHtyfQoKc2V1LnEgPC0gRmluZE5laWdoYm9ycyhzZXUucSwgZGltcyA9IDE6MjUsIGsucGFyYW0gPSA0MykKc2V1LnEgPC0gRmluZENsdXN0ZXJzKHNldS5xLCByZXNvbHV0aW9uID0gYygwLDAuMiwwLjQsMC42KSkKc2V1LnEgPC0gRmluZENsdXN0ZXJzKHNldS5xLCByZXNvbHV0aW9uID0gYygxLjIpKQoKbGlicmFyeShjbHVzdHJlZSkKY2x1c3RyZWUoc2V1LnEsIHByZWZpeCA9ICJSTkFfc25uX3Jlcy4iKQpEaW1QbG90KHNldS5xKQpgYGAKCkxvb2sgYXQgdGhlIHByZWRpY3Rpb25zIGluIHRoZSBuZXcgY2x1c3RlcnMKCmBgYHtyfQojIEFJVzAwMiAxNjAgZGF5cyBwcmVkaWN0aW9ucwp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuNiwgc2V1LnEkTUJPQUlXLnByZWQpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQpnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKSAKdG9wLnByZWQuY2VsbHR5cGUuQUlXMTIwIDwtIGFzLmRhdGEuZnJhbWUodC5sYWJsZXMgICU+JSBncm91cF9ieShWYXIxKSAgJT4lIHRvcF9uKDEsIEZyZXEpKQoKIyBBSVcwMDIgMTYwIGRheXMgcHJlZGljdGlvbnMKdC5sYWJsZXMgPC0gYXMuZGF0YS5mcmFtZSh0YWJsZShzZXUucSRSTkFfc25uX3Jlcy4wLjYsIHNldS5xJEFJVzYwLnByZWQpKQp0LmxhYmxlcyRGcmVxIDwtIGFzLmRvdWJsZSh0LmxhYmxlcyRGcmVxKQpnZ3Bsb3QodC5sYWJsZXMsIGFlcyh5ID0gRnJlcSwgeCA9IFZhcjEsIGZpbGwgPSBWYXIyKSkgKyBnZW9tX2Jhcihwb3NpdGlvbiA9ICJzdGFjayIsIHN0YXQ9ICJpZGVudGl0eSIpICsgUm90YXRlZEF4aXMoKSAKdG9wLnByZWQuY2VsbHR5cGUuQUlXNjAgPC1hcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigxLCBGcmVxKSkKCiMgQVNUMjMgNjUgZGF5cyBwcmVkaWN0aW9ucwp0LmxhYmxlcyA8LSBhcy5kYXRhLmZyYW1lKHRhYmxlKHNldS5xJFJOQV9zbm5fcmVzLjAuNiwgc2V1LnEkTUJPQVNUMjMucHJlZCkpCnQubGFibGVzJEZyZXEgPC0gYXMuZG91YmxlKHQubGFibGVzJEZyZXEpCmdncGxvdCh0LmxhYmxlcywgYWVzKHkgPSBGcmVxLCB4ID0gVmFyMSwgZmlsbCA9IFZhcjIpKSArIGdlb21fYmFyKHBvc2l0aW9uID0gInN0YWNrIiwgc3RhdD0gImlkZW50aXR5IikgKyBSb3RhdGVkQXhpcygpIAp0b3AucHJlZC5jZWxsdHlwZS5BU1QyMyA8LSBhcy5kYXRhLmZyYW1lKHQubGFibGVzICAlPiUgZ3JvdXBfYnkoVmFyMSkgICU+JSB0b3BfbigxLCBGcmVxKSkKCgpwcmVkLnRhYmxlIDwtIG1lcmdlKHRvcC5wcmVkLmNlbGx0eXBlLkFJVzEyMCx0b3AucHJlZC5jZWxsdHlwZS5BSVc2MCwgYnkgPSAnVmFyMScpCnByZWQudGFibGUgPC0gbWVyZ2UocHJlZC50YWJsZSwgdG9wLnByZWQuY2VsbHR5cGUuQVNUMjMsIGJ5ID0gJ1ZhcjEnKQpwcmVkLnRhYmxlCgpgYGAKCkJhc2VkIG9uIHRoZSAzIGRpZmZlcmVudCBwcmVkaWN0aW9ucyBJIGNhbiBsYWJsZSB0aGUgY2VsbCB0eXBlcwoKMCAtIE5QQyBvciBlYXJseSBuZXVyb25zCjEgLSBpbW1hdHVyZSBleGNpdGF0b3J5IG5ldXJvbnMKMiAtIE5QQyBvciBlYXJseSBuZXVyb25zCjMgLSBSRyBvciBPbGlnb3MKNC0gRG9wYW1pbmVyZ2ljIG5ldXJvbnMgLSBwb3NzaWJseSBlYXJseQo1IC0gTlBDIG9yIGVhcmx5IG5ldXJvbnMKNiAtIFJhZGlhbCBHTGlhCgpJIHdpbGwgYWxzbyBmaW5kIG1hcmtlcnMgYW5kIGxvb2sgYXQgYSBsaXN0IG9mIG5ldXJvbmFsIG1hcmtlcnMKCmBgYHtyfQoKSWRlbnRzKHNldS5xKSA8LSAnUk5BX3Nubl9yZXMuMC42JwpDbHVzdGVyTWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhzZXUucSwgb25seS5wb3MgPSBUUlVFKQoKdG9wNSA8LSBDbHVzdGVyTWFya2VycyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKG49NSwgd3QgPSBhdmdfbG9nMkZDKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gdG9wNSRnZW5lLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpCgp3cml0ZS5jc3YoQ2x1c3Rlck1hcmtlcnMsIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvTmV1cm9uczFDbHVzdGVyTWFya2VyczcuY3N2IikKCgpgYGAKCkV4cGxvcmUgc29tZSBHZW5lIGV4cHJlc3Npb24gbGV2ZWxzCgpgYGB7cn0KZmVhdHVyZV9saXN0ID0gYygiTUtJNjciLCJTT1gyIiwiUE9VNUYxIiwiRExYMiIsIlBBWDYiLCJTT1g5IiwiSEVTMSIsIk5FUyIsIlJCRk9YMyIsIk1BUDIiLCJOQ0FNMSIsIkNEMjQiLCJHUklBMiIsIkdSSU4yQiIsIkdBQkJSMSIsIkdBRDEiLCJHQUQyIiwiR0FCUkExIiwiR0FCUkIyIiwiVEgiLCJBTERIMUExIiwiTE1YMUIiLCJOUjRBMiIsIkNPUklOIiwiQ0FMQjEiLCJLQ05KNiIsIkNYQ1I0IiwiSVRHQTYiLCJTTEMxQTMiLCJDRDQ0IiwiQVFQNCIsIlMxMDBCIiwgIlBER0ZSQSIsIk9MSUcyIiwiTUJQIiwiQ0xETjExIiwiVklNIiwiVkNBTTEiKQoKRG9IZWF0bWFwKHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQpEb3RQbG90KHNldS5xLCBmZWF0dXJlcyA9IGZlYXR1cmVfbGlzdCkgK1JvdGF0ZWRBeGlzKCkKClBEX3BvdWxpbiA9IGMoIlRIIiwiU0xDNkEzIiwiU0xDMThBMiIsIlNPWDYiLCJORE5GIiwiU05DRyIsIkFMREgxQTEiLCJDQUxCMSIsIlRBQ1IyIiwiU0xDMTdBNiIsIlNMQzMyQTEiLCJPVFgyIiwiR1JQIiwiTFBMIiwiQ0NLIiwiVklQIikKCkRvSGVhdG1hcChzZXUucSwgZmVhdHVyZXMgPSBQRF9wb3VsaW4sIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC42JykKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBQRF9wb3VsaW4pK1JvdGF0ZWRBeGlzKCkKCmVhbHJ5TmV1ciA9IGMoIkRDWCIsIk5FVVJPRDEiLCJUQlIxIikKcHJvbGlmZXJhdGlvbiA9IGMoIlBDTkEiLCJNS0k2NyIpCm5ldXJhbHN0ZW0gPSBjKCJTT1gyIiwiTkVTIiwiUEFYNiIsIk1BU0gxIikKCmZlYXR1cmVfbGlzdCA8LSBjKCJEQ1giLCJORVVST0QxIiwiVEJSMSIsIlBDTkEiLCJNS0k2NyIsIlNPWDIiLCJORVMiLCJQQVg2IiwiTUFTSDEiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gZmVhdHVyZV9saXN0LCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gZmVhdHVyZV9saXN0KStSb3RhdGVkQXhpcygpCiMgbm8gcHJvbGlmZXJhdGlvbiBtYXJrZXIgZXhwcmVzc2lvbiAgUENOQSBvciBNS0k2NwojIGNsdXN0ZXIgNCBEQSBuZXVyb25zIC0gc2hvd3MgZWFybHkgbmV1cm9uIG1hcmtlciBhbmQgbG93IFBBWCA0CiMgY2x1c3RlciAzIGhhcyBoaWdoZXIgU09YMiAtIG5ldXJvYmxhc3QgbWFya2VyIC8gTlBDIG1hcmtlcgoKbWF0X25ldXJvbiA9IGMoIlJCRk9YMyIsIlNZUCIsIkRMRzQ1IiwiVkFNUDEiLCJWQU1QMiIsIlRVQkIzIiwiU1lUMSIsIkJTTiIsIkhPTUVSMSIsIlNMQzE3QTYiKSAKIyBOZXVOIGlzIEZPWDMgLSBSQkZPWDMKIyBQU0Q5NSBhbHNvIFNQLTkwIG9yIERMRzQKIyBWR0xVVDIgaXMgU0xDMTdBNgpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gbWF0X25ldXJvbiwgc2l6ZT0zLCBhbmdsZSA9OTAsIGdyb3VwLmJhci5oZWlnaHQgPSAwLjAyLCBncm91cC5ieSA9ICdSTkFfc25uX3Jlcy4wLjYnKQojIGNsdXN0ZXIgNCBhbHNvIHNob3cgbWF0dXJlIG5ldXJvbiBtYXJrZXJzCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gbWF0X25ldXJvbikrUm90YXRlZEF4aXMoKQojIGV4Y2l0YXRvcnkgbmV1cm9uIG1hcmtlcnMKZXggPSBjKCJHUklBMiIsIkdSSUExIiwiR1JJQTQiLCJHUklOMSIsIkdSSU4yQiIsIkdSSU4yQSIsIkdSSU4zQSIsIkdSSU4zIiwiR1JJUDEiLCJDQU1LMkEiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gZXgsIHNpemU9MywgYW5nbGUgPTkwLCBncm91cC5iYXIuaGVpZ2h0ID0gMC4wMiwgZ3JvdXAuYnkgPSAnUk5BX3Nubl9yZXMuMC42JykKRG90UGxvdChzZXUucSwgZmVhdHVyZXMgPSBleCkrUm90YXRlZEF4aXMoKQojIGluaGliaXRvcnkgbmV1cm9uIG1hcmtlcnMKaW5oID0gYygiR0FEMSIsIkdBRDIiLCAiR0FUMSIsIlBWQUxCIiwiR0FCUjIiLCJHQUJSMSIsIkdCUlIxIiwiR0FCUkIyIiwiR0FCUkIxIiwiR0FCUkIzIiwiR0FCUkE2IiwiR0FCUkExIiwiR0FCUkE0IiwiVFJBSzIiKQpEb0hlYXRtYXAoc2V1LnEsIGZlYXR1cmVzID0gaW5oLCBzaXplPTMsIGFuZ2xlID05MCwgZ3JvdXAuYmFyLmhlaWdodCA9IDAuMDIsIGdyb3VwLmJ5ID0gJ1JOQV9zbm5fcmVzLjAuNicpCkRvdFBsb3Qoc2V1LnEsIGZlYXR1cmVzID0gaW5oKStSb3RhdGVkQXhpcygpCiMgY2x1c3RlciA0IGlzIG1vcmUgZXhjaXRhdG9yeSB0aGFuIGluaGJpdG9yeSBidXQgbmVpdGhlciBtYXJrZXIgc2V0IGhhcyBtdWNoIGV4cHJlc3Npb24gCgoKCmBgYAoKCkNoZWNrb3V0IHRoZSBFbnJpY2hlciBjZWxsIHR5cGUgbGlicmFyaWVzIGZyb20gCgpgYGB7cn0KIyB0ZXN0IG1hcmtlcnMgZm9yIHRoZSA3IGNsdXN0ZXJzIGluIE5ldXJvbnMxIAoKbGlicmFyeShkZXZ0b29scykKaW5zdGFsbF9naXRodWIoIndqYXdhaWQvZW5yaWNoUiIpCmxpYnJhcnkoZW5yaWNoUikKCgpzZXRFbnJpY2hyU2l0ZSgiRW5yaWNociIpICMgSHVtYW4gZ2VuZXMKIyBsaXN0IG9mIGFsbCB0aGUgZGF0YWJhc2VzCgpkYnMgPC0gbGlzdEVucmljaHJEYnMoKQpkYnMKIyBsaWJhcmllcyB3aXRoIGNlbGwgdHlwZXMKCmRiIDwtIGMoJ0FsbGVuX0JyYWluX0F0bGFzX3VwJywnRGVzY2FydGVzX0NlbGxfVHlwZXNfYW5kX1Rpc3N1ZV8yMDIxJywKICAgICAgICAnQ2VsbE1hcmtlcl9BdWdtZW50ZWRfMjAyMScsJ0F6aW11dGhfQ2VsbF9UeXBlc18yMDIxJykKCiMgZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gTlVMTCkKCk4xLmMwIDwtIENsdXN0ZXJNYXJrZXJzICU+JSBmaWx0ZXIoY2x1c3RlciA9PSAwICYgYXZnX2xvZzJGQyA+IDApCmdlbmVzIDwtIE4xLmMwJGdlbmUKCk4xLmMwLkVyIDwtIGVucmljaHIoZ2VuZXMsIGRhdGFiYXNlcyA9IGRiKQpwbG90RW5yaWNoKE4xLmMwLkVyW1sxXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMwLkVyW1syXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMwLkVyW1szXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQoKTjEuRXIuZ2VuZXMuMSA8LSBOMS5jMC5FcltbMV1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4xCgpOMS5Fci5nZW5lcy4yIDwtIE4xLmMwLkVyW1syXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjIKCk4xLkVyLmdlbmVzLjMgPC0gTjEuYzAuRXJbWzNdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMwoKIyBjbHVzdGVyIDAgY291bGQgYmUgaHlwb3RoYWxtdXMsIERBIG5ldXJvbnMgQTEzCgpOMS5jMSA8LSBDbHVzdGVyTWFya2VycyAlPiUgZmlsdGVyKGNsdXN0ZXIgPT0gMSAmIGF2Z19sb2cyRkMgPiAwKQpnZW5lcyA8LSBOMS5jMSRnZW5lCgpOMS5jMS5FciA8LSBlbnJpY2hyKGdlbmVzLCBkYXRhYmFzZXMgPSBkYikKcGxvdEVucmljaChOMS5jMS5FcltbMV1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMS5FcltbMl1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMS5FcltbM11dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jMS5FcltbNF1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKCk4xLkVyLmdlbmVzLjEgPC0gTjEuYzEuRXJbWzFdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMQoKTjEuRXIuZ2VuZXMuMiA8LSBOMS5jMS5FcltbMl1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4yCgpOMS5Fci5nZW5lcy4zIDwtIE4xLmMxLkVyW1szXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjMKCk4xLkVyLmdlbmVzLjQgPC0gTjEuYzEuRXJbWzRdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuNAoKIyBjbHVzdGVyIDE7IG9sZmFjdG9yeSBidWxiLCBuZXVyYWwgcGxhdGUsIG1heWJlIFJhZGlhbCBHbGlhLCAKTjEuYzIgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDIgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzIkZ2VuZQoKTjEuYzIuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzIuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzIuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzIuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzIuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmMyLkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzIuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jMi5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgpOMS5Fci5nZW5lcy40IDwtIE4xLmMyLkVyW1s0XV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjQKCiMgY2x1c3RlciAyIHNvbWUgYnJhaW4gbnVjbGV1cywgbmV1cmFsIHN0ZW0KCk4xLmMzIDwtIENsdXN0ZXJNYXJrZXJzICU+JSBmaWx0ZXIoY2x1c3RlciA9PSAzICYgYXZnX2xvZzJGQyA+IDApCmdlbmVzIDwtIE4xLmMzJGdlbmUKCk4xLmMzLkVyIDwtIGVucmljaHIoZ2VuZXMsIGRhdGFiYXNlcyA9IGRiKQpwbG90RW5yaWNoKE4xLmMzLkVyW1sxXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMzLkVyW1syXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMzLkVyW1szXV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQpwbG90RW5yaWNoKE4xLmMzLkVyW1s0XV0sIHNob3dUZXJtcyA9IDIwLCBudW1DaGFyID0gNDAsIHkgPSAiQ291bnQiLCBvcmRlckJ5ID0gIlAudmFsdWUiKQoKTjEuRXIuZ2VuZXMuMSA8LSBOMS5jMy5FcltbMV1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4xCgpOMS5Fci5nZW5lcy4yIDwtIE4xLmMzLkVyW1syXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjIKCk4xLkVyLmdlbmVzLjMgPC0gTjEuYzMuRXJbWzNdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMwoKTjEuRXIuZ2VuZXMuNCA8LSBOMS5jMy5FcltbNF1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy40CgojIGNsdXN0ZXIgMyBzdHJvbWFsIGNlbGwgb2YgdGh5bXVzLCBlbWJyeW9uaWMgYXN0cm9jeXRlcywgT1BDLCBOSyBjZWxscywgbW9ub2N5dGVzCgpOMS5jNCA8LSBDbHVzdGVyTWFya2VycyAlPiUgZmlsdGVyKGNsdXN0ZXIgPT0gNCAmIGF2Z19sb2cyRkMgPiAwKQpnZW5lcyA8LSBOMS5jNCRnZW5lCgpOMS5jNC5FciA8LSBlbnJpY2hyKGdlbmVzLCBkYXRhYmFzZXMgPSBkYikKcGxvdEVucmljaChOMS5jNC5FcltbMV1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jNC5FcltbMl1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jNC5FcltbM11dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jNC5FcltbNF1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKCk4xLkVyLmdlbmVzLjEgPC0gTjEuYzQuRXJbWzFdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMQoKTjEuRXIuZ2VuZXMuMiA8LSBOMS5jNC5FcltbMl1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4yCgpOMS5Fci5nZW5lcy4zIDwtIE4xLmM0LkVyW1szXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjMKCk4xLkVyLmdlbmVzLjQgPC0gTjEuYzQuRXJbWzRdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuNAoKIyBEZW50YXRlIGd5cnVzIC0gZGlmZmVyZW50IGNvcnRpY2FsIGxheWVycywgbmV1cm9ucywgbmV1cm9ucywgTlBDLCBuZXVyb25zIEdBQkEsR0xVVAoKTjEuYzUgPC0gQ2x1c3Rlck1hcmtlcnMgJT4lIGZpbHRlcihjbHVzdGVyID09IDUgJiBhdmdfbG9nMkZDID4gMCkKZ2VuZXMgPC0gTjEuYzUkZ2VuZQoKTjEuYzUuRXIgPC0gZW5yaWNocihnZW5lcywgZGF0YWJhc2VzID0gZGIpCnBsb3RFbnJpY2goTjEuYzUuRXJbWzFdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzUuRXJbWzJdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzUuRXJbWzNdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCnBsb3RFbnJpY2goTjEuYzUuRXJbWzRdXSwgc2hvd1Rlcm1zID0gMjAsIG51bUNoYXIgPSA0MCwgeSA9ICJDb3VudCIsIG9yZGVyQnkgPSAiUC52YWx1ZSIpCgpOMS5Fci5nZW5lcy4xIDwtIE4xLmM1LkVyW1sxXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjEKCk4xLkVyLmdlbmVzLjIgPC0gTjEuYzUuRXJbWzJdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMgoKTjEuRXIuZ2VuZXMuMyA8LSBOMS5jNS5FcltbM11dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4zCgpOMS5Fci5nZW5lcy40IDwtIE4xLmM1LkVyW1s0XV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjQKCiMgY2x1c3RlciA1IGhpcHBvY2FtcHVzLCBlbmRvdGhlbGlhbCBjZWxscywgcGVyaWN5dGVzCgpOMS5jNiA8LSBDbHVzdGVyTWFya2VycyAlPiUgZmlsdGVyKGNsdXN0ZXIgPT0gNiAmIGF2Z19sb2cyRkMgPiAwKQpnZW5lcyA8LSBOMS5jNiRnZW5lCgpOMS5jNi5FciA8LSBlbnJpY2hyKGdlbmVzLCBkYXRhYmFzZXMgPSBkYikKcGxvdEVucmljaChOMS5jNi5FcltbMV1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jNi5FcltbMl1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jNi5FcltbM11dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKcGxvdEVucmljaChOMS5jNi5FcltbNF1dLCBzaG93VGVybXMgPSAyMCwgbnVtQ2hhciA9IDQwLCB5ID0gIkNvdW50Iiwgb3JkZXJCeSA9ICJQLnZhbHVlIikKCk4xLkVyLmdlbmVzLjEgPC0gTjEuYzYuRXJbWzFdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuMQoKTjEuRXIuZ2VuZXMuMiA8LSBOMS5jNi5FcltbMl1dICU+JSBzZWxlY3QoVGVybSwgR2VuZXMsIENvbWJpbmVkLlNjb3JlKQpOMS5Fci5nZW5lcy4yCgpOMS5Fci5nZW5lcy4zIDwtIE4xLmM2LkVyW1szXV0gJT4lIHNlbGVjdChUZXJtLCBHZW5lcywgQ29tYmluZWQuU2NvcmUpCk4xLkVyLmdlbmVzLjMKCk4xLkVyLmdlbmVzLjQgPC0gTjEuYzYuRXJbWzRdXSAlPiUgc2VsZWN0KFRlcm0sIEdlbmVzLCBDb21iaW5lZC5TY29yZSkKTjEuRXIuZ2VuZXMuNAoKIyBjbHVzdGVyIDYgYnJhaW4gY29ydGV4LCBzaHdhbm4gY2VsbCwgZW5kb3RoZWxpYWwsIHBlcmljeXRlLCBHQUJBCgoKYGBgCgpMaWJyYXJ5IG9mIHRpc3N1ZSBjZWxsIHR5cGVzIGZvciB1cCByZWd1bGF0ZWQgZ2VuZXMgcGVyIGNsdXN0ZXIKMCAtIGh5cG90aGFsbXVzLCBEQSBBMTMKMS0gbmV1cmFsIHBsYXRlLCBSYWRpYWwgR2xpYQoyIC0gTmV1cmFsIHN0ZW0KMyAtIHN0cm9tYWwsIGFzdHJvIE9QQwo0IC0gTmV1cm9ucwo1IC0gZW5kb3RoZWxpYWwsIHBlcmljeXRlCjYgLSBtYXliZSBuZXVyb25zIG1heWJlIG5vdAoKCkJ5IHRoZSBjb21iaW5lZCBpbmZvcm1hdGlvbiAtIGFubm90YXRlIHRoZSBjbHVzdGVycyBpbiBOZXVyb25zMQoKYGBge3J9CiNCYXNlZCBvbiB0aGUgMyBkaWZmZXJlbnQgcHJlZGljdGlvbnMgSSBjYW4gbGFibGUgdGhlIGNlbGwgdHlwZXMKCiMwIC0gTlBDIG9yIGVhcmx5IG5ldXJvbnMKIzEgLSBpbW1hdHVyZSBleGNpdGF0b3J5IG5ldXJvbnMKIzIgLSBOUEMgb3IgZWFybHkgbmV1cm9ucwojMyAtIFJHIG9yIE9saWdvcwojNC0gRG9wYW1pbmVyZ2ljIG5ldXJvbnMgLSBwb3NzaWJseSBlYXJseQojNSAtIE5QQyBvciBlYXJseSBuZXVyb25zCiM2IC0gUmFkaWFsIEdsaWEKCklkZW50cyhzZXUucSkgPC0gJ1JOQV9zbm5fcmVzLjAuNicKY2x1c3Rlci5pZHMgPC0gYygiSW1tYXR1cmVOZXVyb25zIiwiTmV1cm9ucyIsIk5QQyIsIk9QQy1SRyIsIkRBbmV1cm9ucyIsCiAgICAgICAgICAgICAgICAgIk90aGVyIiwiUkciKQp1bmlxdWUoc2V1LnEkUk5BX3Nubl9yZXMuMC42KQoKbmFtZXMoY2x1c3Rlci5pZHMpIDwtIGxldmVscyhzZXUucSkKc2V1LnEgPC0gUmVuYW1lSWRlbnRzKHNldS5xLCBjbHVzdGVyLmlkcykKc2V1LnEkc3ViZ3JvdXBzIDwtIElkZW50cyhzZXUucSkKCkRpbVBsb3Qoc2V1LnEsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgbGFiZWwgPSBUUlVFLCBncm91cC5ieSA9ICdzdWJncm91cHMnLCByZXBlbCA9IFRSVUUpCgoKc2F2ZVJEUyhzZXUucSwgIi9Vc2Vycy9yaGFsZW5hdGhvbWFzL0RvY3VtZW50cy9EYXRhL3NjUk5Bc2VxL1BoZW5vSUQvc2NSTkFzZXFTb3J0ZWQvb2Jqcy9OZXVyb24xTGFibGVkU2V1MzAwOTIwMjIuUkRTIikKCmBgYAoKCiMjIyBOZXh0IFJlcGVhdCBldmVyeXRoaW5nIGZvciBOZXVyb25zMgoKYGBge3J9CiMgZXhwbG9yZSBmaWx0ZXJpbmcKc2V1IDwtIE5ldXJvbnMyCnNldQpWbG5QbG90KHNldSwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiwgIm5Db3VudF9STkEiLCAicGVyY2VudC5tdCIpLCBuY29sID0gMykKClZsblBsb3Qoc2V1LCBwdC5zaXplID0gMC4xMCwgZmVhdHVyZXMgPSBjKCJuRmVhdHVyZV9STkEiKSwgeS5tYXggPSAyMDAwKQpWbG5QbG90KHNldSwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkZlYXR1cmVfUk5BIiksIHkubWF4ID0gMzUwKQpWbG5QbG90KHNldSwgcHQuc2l6ZSA9IDAuMTAsIGZlYXR1cmVzID0gYygibkNvdW50X1JOQSIpLCB5Lm1heCA9IDIwMDApCgojIGZpbHRlciBtb3JlIGNlbGxzCgpzZXUuZnQgPC0gc3Vic2V0KHNldSwgc3Vic2V0ID0gbkZlYXR1cmVfUk5BID4gMjUwICYgbkNvdW50X1JOQSA+IDI1MCAmIG5Db3VudF9STkEgPCAxMDAwMCkgCnNldS5mdAoKIyAxNzYwNCBzYW1wbGVzIHdpdGggMjUwIG5GZWF0dXJlX1JOQQoKCgpgYGAKCgpEb3VibGV0IGZpbmRlciAKCmBgYHtyfQpzdXBwcmVzc01lc3NhZ2VzKHJlcXVpcmUoRG91YmxldEZpbmRlcikpCgojIGZpbHRlcmluZyBvdXQgTUFMQVQxIGFuZCBtaXRvY2hvbmRyaWFsIGdlbmVzCgpzZXUuZnQgPC0gc2V1LmZ0WyFncmVwbCgiTUFMQVQxIiwgcm93bmFtZXMoc2V1KSksIF0Kc2V1LmZ0IDwtIHNldS5mdFshZ3JlcGwoIl5NVC0iLCByb3duYW1lcyhzZXUuZnQpKSwgXQoKcGFyKG1hciA9IGMoNCwgOCwgMiwgMSkpCkMgPC0gc2V1QGFzc2F5cyRSTkFAY291bnRzCkMgPC0gTWF0cml4Ojp0KE1hdHJpeDo6dChDKS9NYXRyaXg6OmNvbFN1bXMoQykpICogMTAwCm1vc3RfZXhwcmVzc2VkIDwtIG9yZGVyKGFwcGx5KEMsIDEsIG1lZGlhbiksIGRlY3JlYXNpbmcgPSBUKVsyNToxXQpib3hwbG90KGFzLm1hdHJpeCh0KENbbW9zdF9leHByZXNzZWQsIF0pKSwgY2V4ID0gMC4xLCBsYXMgPSAxLCB4bGFiID0gIiUgdG90YWwgY291bnQgcGVyIGNlbGwiLAogICAgY29sID0gKHNjYWxlczo6aHVlX3BhbCgpKSgyNSlbMToyNV0sIGhvcml6b250YWwgPSBUUlVFKQoKIyBsaWtlIGluIHRoZSB0dXRvcmlhbCBJJ20gZm9sbG93aW5nIE1BTEFUMSBpcyB0aGUgdG9wIG1vc3QgZXhwcmVzc2VkIGdlbmUuICBUaGUgdG9wIGdlbmVzIGFyZSBhIGxvdCBvZiBNVCBhbmQgUmlib3NvbWFsIGdlbmVzCgpzZXUuZnRbWyJwZXJjZW50LnJiIl1dIDwtIFBlcmNlbnRhZ2VGZWF0dXJlU2V0KHNldS5mdCwgcGF0dGVybiA9ICJeUlAiKQoKCgpzZXUuZCA9IE5vcm1hbGl6ZURhdGEoc2V1LmZ0KQpzZXUuZCA9IEZpbmRWYXJpYWJsZUZlYXR1cmVzKHNldSwgdmVyYm9zZSA9IEYpCnNldS5kID0gU2NhbGVEYXRhKHNldS5kLCB2YXJzLnRvLnJlZ3Jlc3MgPSBjKCJuRmVhdHVyZV9STkEiLCAicGVyY2VudC5tdCIpLAogICAgdmVyYm9zZSA9IEYpCnNldS5kID0gUnVuUENBKHNldS5kLCB2ZXJib3NlID0gRiwgbnBjcyA9IDIwKQpzZXUuZCA9IFJ1blVNQVAoc2V1LmQsIGRpbXMgPSAxOjEwLCB2ZXJib3NlID0gRikKCm5FeHAgPC0gcm91bmQobmNvbChzZXUuZCkgKiAwLjIwKSAgIyBleHBlY3QgbW9yZSBkb3VibGV0cyBiZWNhdXNlIHRoZXJlIGlzIGEgbG90IG1vcmUgY2VsbHMKc2V1LmQgPC0gZG91YmxldEZpbmRlcl92MyhzZXUuZCwgcE4gPSAwLjI1LCBwSyA9IDAuMDksIG5FeHAgPSBuRXhwLCBQQ3MgPSAxOjEwKQoKCiMgbmFtZSBvZiB0aGUgREYgcHJlZGljdGlvbiBjYW4gY2hhbmdlLCBzbyBleHRyYWN0IHRoZSBjb3JyZWN0IGNvbHVtbiBuYW1lLgpERi5uYW1lID0gY29sbmFtZXMoc2V1LmRAbWV0YS5kYXRhKVtncmVwbCgiREYuY2xhc3NpZmljYXRpb24iLCBjb2xuYW1lcyhzZXUuZEBtZXRhLmRhdGEpKV0KCgoKY293cGxvdDo6cGxvdF9ncmlkKG5jb2wgPSAyLCBEaW1QbG90KHNldS5kLCBncm91cC5ieSA9ICJvcmlnLmlkZW50IikgKyBOb0F4ZXMoKSwKICAgIERpbVBsb3Qoc2V1LmQsIGdyb3VwLmJ5ID0gREYubmFtZSkgKyBOb0F4ZXMoKSkKClZsblBsb3Qoc2V1LmQsIGZlYXR1cmVzID0gIm5GZWF0dXJlX1JOQSIsIGdyb3VwLmJ5ID0gREYubmFtZSwgcHQuc2l6ZSA9IDAuMSkKCgpgYGAKCgoKCg==